首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Unix to-Unix编码(to编码)

Unix to-Unix编码(to编码)
EN

Code Review用户
提问于 2016-08-24 04:33:26
回答 2查看 555关注 0票数 6

to编码历来用于对电子邮件进行编码。创建Uu编码器的说明如下:

  1. 从源开始使用3个字节,总共24位。
  2. 分为4组6位分组,每组代表0到63范围内的值:位数(00-05)、(06-11)、(12-17)和(18-23)。
  3. 将32添加到每个值。加上32,这意味着可能的结果可以是32 (“空格”)到95 ("_“下划线)。96 ("`“严重重音)作为”特殊字符“是这一范围的合乎逻辑的延伸。
  4. 输出相当于这些数字的ASCII。
代码语言:javascript
复制
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
EN

回答 2

Code Review用户

发布于 2016-08-24 06:18:06

这在某种程度上是非结构化的,但以下是一些建议:

在对内置

进行跟踪时要小心

dec_to_bin()中,int参数隐藏Python int类型关键字。这很好,但是如果可能的话,避免重新定义内置程序通常会更清楚。也许叫它num

bytes也是一个内置的。重新定义它们是没问题的,只是要注意。

变量并不总是定义

代码语言:javascript
复制
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

不必要的向列表

的转换

代码语言:javascript
复制
char_list = list(string)
...
for char in char_list: ...

字符串和列表一样是可迭代的,所以for char in string:工作得很好。

实际上,考虑完全删除string_valueschar_list。你可以把它们浓缩成:

代码语言:javascript
复制
bytes = ''.join(dec_to_bin(ord(char)) for char in string)

未使用变量

一个常见的约定是使用_来表示未使用的vars:

代码语言:javascript
复制
for index, _ in enumerate(decimal_list):
    decimal_list[index] += 32

这表明您故意忽略了来自enumerate的第二个值。

票数 6
EN

Code Review用户

发布于 2016-08-24 12:08:02

@BenC谦逊地提到,他的答案“有点非结构化”,但尽管他的回答很好,但我觉得这种对缺乏结构的关注适用于您的代码。

您的代码将所有逻辑封装在一个函数中(除了一个微小的助手),这是很难测试、很难编写和很难阅读的。

该算法很好地实现了模块化:对原始消息的每块3字节应用相同的转换。

每个函数都可以配置一个docstring来描述其用途、一个指向进一步文档的链接以及一些提高可读性的示例。

我的这个uuencode_chunk版本还使用了块函数(取自StackOverflow)来进一步划分复杂性,因为这个块逻辑在两个地方都是必需的:

代码语言:javascript
复制
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_chunkchunks,主要功能应该更短、更简单。

票数 3
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/139488

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档