2013-05-16 18 views
7

Ruby's Base64.encode kaynağına bakarak Bir dizeyi kodlayan karakterin, Base64'te bu veriyi kodlamadan önce dönüştürülmediğini belirleyemiyorum. Base64'te kodlanmış bir Utf-8 dizesi, Base64'te kodlanmış bir Utf-16 dizgisinden çok farklı olacaktır. Ruby bu operasyonla ilgili herhangi bir söz veriyor mu? kodlamak ve base64 bir utf-8 dize çözmek içinBase64.encode'u kullanırken Ruby karakter kodlaması

cevap

5

fine manual bunu söylemek etti:

encode64 (bin)
Base64- İade bin kodlanmış sürümü.

6,8: Bu yöntem RFC 2045.

Bölüm RFC 2045 6.8 diyor uymaktadır. Base64 Content-Transfer-Kodlama

Base64 İçerik Aktarımı Kodlama, oktetlerin isteğe bağlı sekanslarını insanca okunabilir olmayan bir biçimde temsil edecek şekilde tasarlanmıştır. [...]

Yazdırılabilir karakter başına 6 bitin gösterilmesini sağlayan 65 karakterlik bir US-ASCII alt kümesi kullanılır. (Ekstra 65 karakter, "=", özel bir işleme fonksiyonunu belirtmek için kullanılır.)

Yani Base64 ASCII içine bayt kodlar. Bu bayt aslında bir UTF-8 kodlanmış dizeyi temsil ediyorsa, UTF-8 dizesi tek tek baytlara bölünür ve bu baytlar Base64'e dönüştürülür; Örneğin, bir UTF-8 dizginiz 'µ' varsa, 0xc2 ve 0xb5 baytlarını (bu sırayla) Base64 gösterimi "wrU=\n"'a kodlamaktan sonlanırsınız. "\xc2\xb5" ('µ''un UTF-8 sürümü ile eşleşecek şekilde) bir ikili dize ile başlarsanız, aynı "wrU=\n" çıktısını alırsınız.

Eğer "wrU=\n" deşifre

, sen bayt "\xc2\xb5" alırsınız ve bu bayt UTF-8 kodlu metin yerine bit bazı keyfi damla gerekiyordu olduğunu bilmek gerekir. Bu nedenle, Base64'e eklenmiş ayrı içerik türü ve karakter kümesi meta verileriniz vardır.

Benzer şekilde, eğer bir UTF-16 dizginiz varsa, bu baytlara bölünür ve bu baytlar diğer bayt dizgileri gibi kodlanır. Tabii ki bu durum bayt düzeniyle ilgili sorunlardan dolayı biraz daha karmaşıktır, ancak bu nedenle içerik türü ve karakter kümesi üstbilgileri ve BOM'lar vardır.

Ana nokta, Base64'ün bayt ile karakterlerin değil, çalıştığıdır. Hangi format (UTF-8 metin, UTF-16 metni, PNG görüntüsü, ...) başkasının problemidir. Base64 sadece bir bayt akışını ABD ASCII'nin bir alt kümesine ve daha sonra baytlara dönüştürür; Bu baytların formatı ayrıca belirtilmelidir.


Bazı kaynağı çevresinde alay ve onlar tamamen alakalı olmasa bile sonuç ilginç olabilecek yaptı.Eğer Array#pack bakmak Sonra

def encode64(bin) 
    [bin].pack("m") 
end 

:

static VALUE 
pack_pack(VALUE ary, VALUE fmt) 
{ 
    /*...*/ 
    int enc_info = 1;  /* 0 - BINARY, 1 - US-ASCII, 2 - UTF-8 */ 

ve enc_info göz kulak Eğer bir 'm' biçim dolu dize kadar yalnız enc_info bırakacağını göreceksiniz encode64 method basitçe şudur US-ASCII olarak çıkacak ve encode64 beklendiği gibi ABD ASCII çıkışı üretecektir.

+0

Bu, Victor'un cevabının yorumlarındaki şüphelerimi kabul eder. Doğrulama için teşekkürler. – Brent

19

Bir örnek:

text = "intérnalionálização" 
=> "intérnalionálização" 
text.encoding 
=> #<Encoding:UTF-8> 
encoded = Base64.encode64(text) 
=> "aW50w6lybmFsaW9uw6FsaXphw6fDo28=\n" 
encoded.encoding 
=> #<Encoding:US-ASCII> 
decoded = Base64.decode64(encode) 
=> "int\xC3\xA9rnalion\xC3\xA1liza\xC3\xA7\xC3\xA3o" 
decoded.encoding 
=> #<Encoding:US-ASCII> 
decoded = decoded.force_encoding('UTF-8') 
=> "intérnalionálização" 
decoded.encoding 
=> #<Encoding:UTF-8> 
+0

İlginç. Decode64'den döndürülen dize US-ASCII'dir ve bir kaç kaçış karakter içerir. Sanırım, bunu base64 kodlamadan önce US-ASCII'ye çevirdiği oldukça iyi bir gösterge. – Brent

+1

Anlamak için: http://api.rubyonrails.org/classes/Base64.html ve http://apidock.com/ruby/Array/pack –

+1

Victor'un kodunu irb oturumunda denemek istiyorsanız, emin olun İlk önce 'base64' gerektirir. – Gokul

İlgili konular