to编码历来用于对电子邮件进行编码。创建Uu编码器的说明如下:
import platform
def dec_to_bin(int):
return bin(int).replace('0b', '')
def uuencode(string, filename):
if platform.system() == 'Windows':
mode = '644'
elif platform.system() == 'Linux':
mode = '744'
trail = 'begin ' + mode + ' ' + filename + '\n'
string_values = []
char_list = list(string)
bytes = ''
for char in char_list:
string_values.append(ord(char))
for ascii in string_values:
bytes += dec_to_bin(ascii)
three_byte = [bytes[p:p+24] for p in range(0, len(bytes), 24)]
if len(three_byte[-1]) < 24:
three_byte[-1] += (24 - len(three_byte[-1])) * '0'
four_six_bits = [three_byte[n][m:m+6] for n in range(len(three_byte)) for m in range(0, 24, 6)]
four_six_bits = [four_six_bits[k:k+4] for k in range(0, len(four_six_bits), 4)]
decimal_list = []
for x in range(len(four_six_bits)):
for z in range(4):
decimal_list.append(int(four_six_bits[x][z], 2))
for index, decimal in enumerate(decimal_list):
decimal_list[index] += 32
encoded_chars = [chr(decimal_list[o]) for o in range(len(decimal_list))]
length_char = chr(len(encoded_chars) + 32)
trail += length_char
for newchar in encoded_chars:
trail += newchar
trail += '\n' + '`' + '\n' + 'end' + '\n'
return trail发布于 2016-08-24 06:18:06
这在某种程度上是非结构化的,但以下是一些建议:
进行跟踪时要小心
在dec_to_bin()中,int参数隐藏Python int类型关键字。这很好,但是如果可能的话,避免重新定义内置程序通常会更清楚。也许叫它num。
bytes也是一个内置的。重新定义它们是没问题的,只是要注意。
if platform.system() == 'Windows':
mode = '644'
elif platform.system() == 'Linux':
mode = '744'
trail = 'begin ' + mode + ' ' + filename + '\n'如果platform.system()既不是Windows也不是Linux,会发生什么?(例如:在Mac上,它返回'Darwin'.) mode将是未定义的,从而引发UnboundLocalError。
的转换
char_list = list(string)
...
for char in char_list: ...字符串和列表一样是可迭代的,所以for char in string:工作得很好。
实际上,考虑完全删除string_values和char_list。你可以把它们浓缩成:
bytes = ''.join(dec_to_bin(ord(char)) for char in string)一个常见的约定是使用_来表示未使用的vars:
for index, _ in enumerate(decimal_list):
decimal_list[index] += 32这表明您故意忽略了来自enumerate的第二个值。
发布于 2016-08-24 12:08:02
@BenC谦逊地提到,他的答案“有点非结构化”,但尽管他的回答很好,但我觉得这种对缺乏结构的关注适用于您的代码。
您的代码将所有逻辑封装在一个函数中(除了一个微小的助手),这是很难测试、很难编写和很难阅读的。
该算法很好地实现了模块化:对原始消息的每块3字节应用相同的转换。
每个函数都可以配置一个docstring来描述其用途、一个指向进一步文档的链接以及一些提高可读性的示例。
我的这个uuencode_chunk版本还使用了块函数(取自StackOverflow)来进一步划分复杂性,因为这个块逻辑在两个地方都是必需的:
import doctest
def padded_decimal_to_bin(i):
return (bin(i).replace('0b', '')).rjust(8, "0")
def chunks(l, n):
"""
Yield successive n-sized chunks from l.
Credit to: http://stackoverflow.com/questions/312443/how-do-you-split-a-list-into-evenly-sized-chunks-in-python
>>> list(chunks([1, 2, 3, 4, 5, 6], 2))
[[1, 2], [3, 4], [5, 6]]
"""
for i in range(0, len(l), n):
yield l[i:i + n]
def uuencode_chunk(chunk):
"""
Given a chunk of 3 bytes (24 bits),
splits it in 4 equal groups of 6, adds 32 to each
and represents them as ASCII characters.
See this section for details:
https://en.wikipedia.org/wiki/Uuencoding#Formatting_mechanism
>>> uuencode_chunk("Cat")
'0V%T'
"""
bits = [padded_decimal_to_bin(ord(char)) for char in chunk]
return ''.join(chr(int(b, base=2) + 32) for b in chunks(''.join(bits), 6))
doctest.testmod()利用uuencode_chunk和chunks,主要功能应该更短、更简单。
https://codereview.stackexchange.com/questions/139488
复制相似问题