patternpythonMinor
Unix-to-Unix Encoding (Uuencoding)
Viewed 0 times
unixuuencodingencoding
Problem
Uuencoding is historically used to encode emails. Instructions for creating a Uuencoder are:
- Start with 3 bytes from the source, 24 bits in total.
- Split into 4 6-bit groupings, each representing a value in the range 0 to 63: bits (00-05), (06-11), (12-17) and (18-23).
- Add 32 to each of the values. With the addition of 32 this means that the possible results can be between 32 (" " space) and 95 ("_" underline). 96 ("`" grave accent) as the "special character" is a logical extension of this range.
- Output the ASCII equivalent of these numbers.
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 trailSolution
This is somewhat unstructured, but here are a few recommendations:
Be careful when shadowing built-ins
In
Variables not always defined
What happens if
Unnecessary conversion to list
Strings are iterable just like lists, so
In fact, consider removing
Unused variable
A common convention is to use
This shows that you are deliberately ignoring the second value from
Be careful when shadowing built-ins
In
dec_to_bin(), the int parameter shadows the Python core int type keyword. This works fine, but it's usually clearer to avoid redefining builtins when you can. Maybe call it num.bytes is also a builtin. It's ok to redefine them, just be aware.Variables not always defined
if platform.system() == 'Windows':
mode = '644'
elif platform.system() == 'Linux':
mode = '744'
trail = 'begin ' + mode + ' ' + filename + '\n'What happens if
platform.system() is neither Windows or Linux? (For example: on Mac it returns 'Darwin'.) mode will be undefined, raising UnboundLocalError.Unnecessary conversion to list
char_list = list(string)
...
for char in char_list: ...Strings are iterable just like lists, so
for char in string: works fine.In fact, consider removing
string_values and char_list entirely. You can condense them into:bytes = ''.join(dec_to_bin(ord(char)) for char in string)Unused variable
A common convention is to use
_ to represent unused vars:for index, _ in enumerate(decimal_list):
decimal_list[index] += 32This shows that you are deliberately ignoring the second value from
enumerate.Code Snippets
if platform.system() == 'Windows':
mode = '644'
elif platform.system() == 'Linux':
mode = '744'
trail = 'begin ' + mode + ' ' + filename + '\n'char_list = list(string)
...
for char in char_list: ...bytes = ''.join(dec_to_bin(ord(char)) for char in string)for index, _ in enumerate(decimal_list):
decimal_list[index] += 32Context
StackExchange Code Review Q#139488, answer score: 6
Revisions (0)
No revisions yet.