簡體   English   中英

base64編碼python 2.7中的unicode字符串

[英]base64 encoding unicode strings in python 2.7

我有一個使用requests模塊從webservice檢索到的unicode字符串, 模塊 包含二進制文檔的字節 (PCL,當它發生時)。 其中一個字節的值為248,嘗試對其進行base64編碼會導致以下錯誤:

In [68]: base64.b64encode(response_dict['content']+'\n')
---------------------------------------------------------------------------
UnicodeEncodeError                        Traceback (most recent call last)
C:\...\<ipython-input-68-8c1f1913eb52> in <module>()
----> 1 base64.b64encode(response_dict['content']+'\n')

C:\Python27\Lib\base64.pyc in b64encode(s, altchars)
     51     """
     52     # Strip off the trailing newline
---> 53     encoded = binascii.b2a_base64(s)[:-1]
     54     if altchars is not None:
     55         return _translate(encoded, {'+': altchars[0], '/': altchars[1]})

UnicodeEncodeError: 'ascii' codec can't encode character u'\xf8' in position 272: ordinal not in range(128)

In [69]: response_dict['content'].encode('base64')
---------------------------------------------------------------------------
UnicodeEncodeError                        Traceback (most recent call last)
C:\...\<ipython-input-69-7fd349f35f04> in <module>()
----> 1 response_dict['content'].encode('base64')

C:\...\base64_codec.pyc in base64_encode(input, errors)
     22     """
     23     assert errors == 'strict'
---> 24     output = base64.encodestring(input)
     25     return (output, len(input))
     26

C:\Python27\Lib\base64.pyc in encodestring(s)
    313     for i in range(0, len(s), MAXBINSIZE):
    314         chunk = s[i : i + MAXBINSIZE]
--> 315         pieces.append(binascii.b2a_base64(chunk))
    316     return "".join(pieces)
    317

UnicodeEncodeError: 'ascii' codec can't encode character u'\xf8' in position 44: ordinal not in range(128)

我發現這有點令人驚訝,因為248在無符號字節的范圍內(並且可以保存在字節字符串中),但我真正的問題是: 對這個字符串進行編碼的最佳或正確方法什么?

我目前的解決方法是:

In [74]: byte_string = ''.join(map(compose(chr, ord), response_dict['content']))

In [75]: byte_string[272]
Out[75]: '\xf8'

這似乎工作正常,並且生成的byte_string能夠進行base64編碼,但似乎應該有更好的方法。 在那兒?

你有一個你想要base64編碼的unicode字符串。 問題是b64encode()只適用於字節 ,而不適用於字符 因此,您需要將unicode字符串(這是一系列抽象的Unicode代碼點)轉換為字節字符串。

將抽象Unicode字符串映射到具體的字節序列稱為編碼 Python支持多種編碼; 我建議廣泛使用的UTF-8編碼:

byte_string = response_dict['content'].encode('utf-8')

請注意,無論是誰解碼字節,還需要知道通過互補decode()函數使用哪個編碼來獲取unicode字符串:

# Decode
decoded = byte_string.decode('utf-8')

學習更多關於Unicode和編碼的一個很好的起點是Python文檔 ,以及Joel Spolsky 撰寫的這篇文章

我建議在base64編碼之前首先將它編碼為類似UTF-8的東西:

In [12]: my_unicode = u'\xf8'

In [13]: my_utf8 = my_unicode.encode('utf-8')

In [15]: base64.b64encode(my_utf8)
Out[15]: 'w7g='

由於您正在使用二進制數據,我不確定使用utf-8編碼是個好主意。 我想這取決於你打算如何使用base64編碼表示。 我認為如果您可以將數據檢索為字節字符串而不是unicode字符串可能會更好。 我從未使用過請求庫,但瀏覽文檔表明它是可能的。 有部分討論“二進制響應內容”和“原始響應內容”。

應該可以將響應作為二進制字節獲取並完全跳過解碼和編碼步驟。 requests總是有可能選擇在往返中丟失一些數據或錯誤的編碼。

這部分稱為“二元響應內容”的文檔似乎完全符合您的問題。

如果它是二進制數據...為什么編碼/解碼呢? 特別是“base64.encodestring”部分。 下面是我如何將圖像編碼到base64中直接添加到我的python代碼而不是有額外的文件。 2.7.2順便說一句

import base64
iconfile = open("blah.icon","rb")
icondata = iconfile.read()
icondata = base64.b64encode(icondata)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM