2017-05-09 43 views
0

背故事,這裏是一個有點冗長,但基本上我想帶像b'\x04\x0e\x1d'一個字符串,將它轉換回至ByteArray。Python的3.x中 - 轉換爲bytearray的字符串表示回字符串

我工作的一個基本實現一次性墊,在這裏我把明文A和共享密鑰B以產生密文C accoring方程A⊕B=C。然後我用方程C⊕B=A來逆轉這個過程。

我已經找到了很多的python3功能編碼字符串作爲字節,然後異或字節,如下列:

def xor_strings(xs, ys): 
    return "".join(chr(ord(x)^ord(y)) for x, y in zip(xs, ys)).encode() 

xor_strings()調用然後返回一個字節組:

print(xor_strings("foo", "bar")) 

但是當我將它打印到屏幕上時,我所顯示的實際上是一個字符串。所以我假設蟒蛇只是呼籲ByteArray的一些str()功能,我得到的東西看起來像下面這樣:

b'\x04\x0e\x1d'

這裏存在的問題。我想從該字符串創建一個新的bytearray。通常我會在字節數組中調用decode()。但是如果我輸入'b'\ x04 \ x0e \ x1d'作爲輸入,python將它視爲一個字符串,而不是一個字節數組!

我怎麼能採取像b'\x04\x0e\x1d'作爲用戶輸入一個字符串,將它轉換回至ByteArray?

+0

您不能將調用「join」的結果存儲到變量中嗎? xor_strings已經返回一個字節數組。 –

+1

我有點困惑。 'b'\ x04 \ x0e \ x1d''不是一個字符串,它是一個字節數組。或者你想讓用戶在文本框中輸入「b'\ x04 \ x0e \ x1d'」? – Tomalak

+0

@EnricoBorba問題在於,在對我的消息進行加密後,我想將其打印到屏幕上,以便將其複製併發送給朋友。然後,他們應該能夠接受該字符串,將其粘貼爲輸入,並且程序應該能夠將該字符串再次識別爲字節數組,而不是字符串 – CryptoCat

回答

3

正如評論中所述,使用base64以文本形式發送二進制數據。

import base64 

def xor_strings(xs, ys): 
    return "".join(chr(ord(x)^ord(y)) for x, y in zip(xs, ys)).encode() 

# ciphertext is bytes 
ciphertext = xor_strings("foo", "bar") 
# >>> b'\x04\x0e\x1d' 

# ciphertext_b64 is *still* bytes, but only "safe" ones (in the printable ASCII range) 
ciphertext_b64 = base64.encodebytes(ciphertext) 
# >>> b'BA4d\n' 

現在我們可以傳送字節:

# ...we could interpret them as ASCII and print them somewhere 
safe_string = ciphertext_b64.decode('ascii') 
# >>> BA4d 

# ...or write them to a file (or a network socket) 
with open('/tmp/output', 'wb') as f: 
    f.write(ciphertext_b64) 

而且收件人可以通過檢索原始消息:當談到字節寫入文件或

# ...reading bytes from a file (or a network socket) 
with open('/tmp/output', 'rb') as f: 
    ciphertext_b64_2 = f.read() 

# ...or by reading bytes from a string 
ciphertext_b64_2 = safe_string.encode('ascii') 
# >>> b'BA4d\n' 

# and finally decoding them into the original nessage 
ciphertext_2 = base64.decodestring(ciphertext_b64_2) 
# >>> b'\x04\x0e\x1d' 

當然對網絡來說,首先將它們編碼爲base64是多餘的。如果它是唯一的文件內容,您可以直接寫/讀密文。只有將它作爲更高結構(JSON,XML,配置文件...)的一部分的密文再次編碼爲base64纔是必要的。

上使用的話「解碼」和「編碼」的音符。

  • 編碼一個字符串意味着把它從它的抽象意義(「一個字符的列表」)成可存儲的表示(「字節的列表」)。此操作的確切結果取決於正在使用的字節編碼。例如:

    • ASCII編碼將一個字符映射到一個字節(作爲一種權衡,它不能映射可以存在於Python字符串中的所有字符)。
    • UTF-8編碼將一個字符映射到1-5個字節,具體取決於字符。
  • 解碼一個字節數組是指從「一個字節的列表」再次打開回「一個字符的列表」。這當然需要事先知道什麼是字節編碼。上述

ciphertext_b64是字節的列表,並且被表示爲b'BA4d\n' Python的控制檯上。

由於base64是ASCII的子集,因此在打印到控制檯時,其字符串等效項safe_string看起來非常類似'BA4d\n'

數據類型但是仍然有根本的不同。不要讓控制檯輸出欺騙你。

2

迴應只有最後一個問題。

>>> type(b'\x04\x0e\x1d') 
<class 'bytes'> 
>>> bytearray(b'\x04\x0e\x1d') 
bytearray(b'\x04\x0e\x1d') 
>>> type(bytearray(b'\x04\x0e\x1d')) 
<class 'bytearray'>