Python уже имеет встроенную поддержку для кодирования и декодирования uuencoded сообщений.
from codecs import encode # decode also works
print(encode("my message", 'uu'))
# -> 'begin 666 <data>\n*;7D@;65S<V%G90 \n \nend\n'
Внутренне Python использует пакет binascii
для кодирования или декодирования сообщения построчно.Мы можем использовать это для кодирования одного байта или даже всех байтов в range(64)
(потому что uuencoding преобразует 6 бит в символ ascii: 2**6 == 64
).
Для генерации всех необходимых битовых комбинаций мы можем считать до 64и сдвинуть результат на 2 бита влево.Таким образом, старшие 6 бит считаются от 0 до 64. Тогда нужно просто преобразовать их в python bytes
, uuencode их и извлечь фактический символ.
В python2
from binascii import b2a_uu
for byte in range(64):
pattern = chr(byte << 2) # str and bytes are identical in python2
encoded = b2a_uu(pattern)
character = encoded[1] # encoded[0] is the character count in that line
print "{:2} -> {!r}".format(byte, character)
В python3 первая часть немного некрасива.
from binascii import b2a_uu
for byte in range(64):
pattern = bytes([byte << 2]) # chr().encode() will not work!
encoded = b2a_uu(pattern)
character = chr(encoded[1])
print(f"{byte:2} -> {character!r}")
Спасибо Марку Рэнсом, который объяснил, почему сдвиг битов действительно работает.