2009-09-11 8 views
6

Khi xem mã hóa 64 cơ sở an toàn của URL, tôi đã tìm thấy nó là một điều rất không chuẩn. Mặc dù số lượng các hàm dựng sẵn có sẵn mà PHP đã có, nhưng không có một hàm mã hóa 64 cơ sở an toàn cho URL. Trên trang hướng dẫn cho base64_encode(), hầu hết các ý kiến ​​đề nghị sử dụng mà chức năng, được bao bọc bởi strtr():Việc thay thế ký tự nào cần được thực hiện để làm cho URL mã hóa cơ sở 64 an toàn?

function base64_url_encode($input) 
{ 
    return strtr(base64_encode($input), '+/=', '-_,'); 
} 

Các module Perl duy nhất tôi có thể tìm thấy trong lĩnh vực này là MIME::Base64::URLSafe (source), trong đó thực hiện việc thay đổi sau đây trong nội bộ:

sub encode ($) { 
    my $data = encode_base64($_[0], ''); 
    $data =~ tr|+/=|\-_|d; 
    return $data; 
} 

không giống như các chức năng PHP ở trên, phiên bản Perl này giọt '=' (bằng) nhân vật hoàn toàn, chứ không phải thay thế nó bằng '' (dấu phẩy) như PHP làm. Bằng là một ký tự đệm, do đó, mô-đun Perl thay thế chúng khi cần thiết khi giải mã, nhưng sự khác biệt này làm cho hai triển khai không tương thích.

Cuối cùng, hàm Python urlsafe_b64encode(s) giữ '=' đệm xung quanh, khiến một người nào đó để đưa lên this function để loại bỏ các đệm trong đó cho thấy nổi bật trong kết quả của Google cho 'python base64 url safe':

from base64 import urlsafe_b64encode, urlsafe_b64decode 

def uri_b64encode(s): 
    return urlsafe_b64encode(s).strip('=') 

def uri_b64decode(s): 
    return urlsafe_b64decode(s + '=' * (4 - len(s) % 4)) 

Mong muốn ở đây là để có một chuỗi có thể được bao gồm trong URL mà không cần mã hóa thêm, do đó là bỏ hoặc dịch các ký tự '+', '/' và '='. Vì không có tiêu chuẩn được xác định, đúng cách là gì?

Trả lời

9

Hiện không có vẻ như là một tiêu chuẩn, nó là RFC 3548, Mục 4, Base 64 Encoding với URL và Tên tập tin an toàn Alphabet:

mã hóa này là về mặt kỹ thuật giống hệt với trước đó, ngoại trừ các 62: nd và 63: nhân vật bảng chữ cái thứ, như đã nêu trong bảng 2.

+/ nên được thay thế d lần lượt là - (minus)_ (understrike). Bất kỳ thư viện không phù hợp nên được bọc để họ phù hợp với RFC 3548.

Lưu ý rằng điều này đòi hỏi bạn phải URL mã hóa (pad) = ký tự, nhưng tôi thích điều đó trên URL mã hóa các +/ ký tự từ chữ base64 chuẩn.

0

Tại sao bạn không thử gói nó trong một số urlencode()? Tài liệu here.

+1

Điều đó sử dụng số ký tự không cần thiết. Tại sao không chỉ urlencode chuỗi nhị phân ở nơi đầu tiên? – recursive

2

Tôi khuyên bạn nên chạy đầu ra của base64_encode thông qua urlencode. Ví dụ:

function base64_encode_url($str) 
{ 
    return urlencode(base64_encode($str)); 
} 
1

Nếu bạn hỏi về cách chính xác, tôi sẽ sử dụng mã hóa URL phù hợp thay vì tùy ý thay thế các ký tự. Đầu tiên mã hóa base64 dữ liệu của bạn, sau đó mã hóa thêm các ký tự đặc biệt như "=" với mã hóa URL thích hợp (ví dụ: %<code>).

+0

Tôi đang sử dụng các chức năng đã có sẵn, nhưng việc sử dụng urlencode() có thể tăng thêm rất nhiều thời gian. –

8

Tôi không nghĩ đúng hay sai.Nhưng mã hóa phổ biến nhất là

'+/=' => '-_.' 

Điều này được sử dụng rộng rãi bởi Google, Yahoo (gọi là Y64). Phiên bản mã hóa an toàn nhất của url mà tôi đã sử dụng trên Java, Ruby hỗ trợ bộ ký tự này.

+0

+1 để đề cập đến Y64 và thêm một số nền văn hóa cho câu hỏi – jmserra