Python: How to decode uuencoded text

7.2k Views Asked by At

I've been reading about uuencoding and was wondering how to decode the following example given in this link using Python.

https://en.wikipedia.org/wiki/Uuencoding

Original text: Cat

Uuencoded text: #0V%T

Python 2

$ python -c 'print "Cat".encode("uu")'
begin 666 <data>
#0V%T

end

$

Python 3

$ python3 -c "from codecs import encode;print(encode(b'Cat', 'uu'))"
b'begin 666 <data>\n#0V%T\n \nend\n'
$
2

There are 2 best solutions below

0
Tim Seed On

It is just the inverse of the original function....

Let me try and show you. I will use 2 common encoding type uu and base-64.

Python 3

from codecs import decode,encode
import uu

orig="Cat"
encoding_types=['uu','base-64']
for et in encoding_types:
    enc_data=encode(orig.encode(),et)
    un_enc_data=decode(enc_data,et)
    print("\n\nEncoding  : {}".format(et))
    print("Orig          : {}".format(orig))
    print("Encoded       : {}".format(enc_data))
    print("byte UnEncoded: {}".format(un_enc_data))
    print("utf8 UnEncoded: {}".format(un_enc_data.decode()))

This should output

Encoding  : uu
Orig          : Cat
Encoded       : b'begin 666 <data>\n#0V%T\n \nend\n'
byte UnEncoded: b'Cat'
utf8 UnEncoded: Cat


Encoding  : base-64
Orig          : Cat
Encoded       : b'Q2F0\n'
byte UnEncoded: b'Cat'
utf8 UnEncoded: Cat

We need the final .decode() as we initially converted the str data object into bytes with the encode().

2
ultimate-anti-reversing On

The library uu is now deprecated.

See here and here. Even codecs relies on uu. See here.

You should use binascii:

c="02&DA($AO=R!A<F4@>6]U/P``"
 
import binascii
m = binascii.a2b_uu(c)
print(m)

Then you can read:

Hi! How are you?

.

You might need to implement uu encoding alone or to choose another library.

To write your own library, do:

def get_bits(num, start, end, length=64):
    mask = 2**(end-start)-1
    shift = length - (end-start) - start

    return (num & (mask << shift)) >> shift


def decode_uu_charset(cipher_text):
        plain_text = ""

        three_characters = []
        for character_group in list(zip(*[iter(cipher_text[1:len(cipher_text)])] * 4)):
            character_group = "".join(character_group)
            four_six_bits = []
            for c in character_group:
                c = bin((ord(c) - 32) % 64)[2:].zfill(6)
                four_six_bits.append(c)
            three_characters.append(
                chr(int(str(bin(get_bits(int(four_six_bits[0], 2), 0, 6, 6))[2:].zfill(6)) +
                str(bin(get_bits(int(four_six_bits[1], 2), 0, 2, 6))[2:].zfill(2)), 2))
            )
            three_characters.append(
                chr(int(str(bin(get_bits(int(four_six_bits[1], 2), 2, 6, 6))[2:].zfill(4)) +
                str(bin(get_bits(int(four_six_bits[2], 2), 0, 4, 6))[2:].zfill(4)), 2))
            )
            three_characters.append(
                chr(int(str(bin(get_bits(int(four_six_bits[2], 2), 4, 6, 6))[2:].zfill(2)) +
                str(bin(get_bits(int(four_six_bits[3], 2), 0, 6, 6))[2:].zfill(6)), 2))
            )
        for c in three_characters:
            if ord(c) != 0:
                plain_text += c

        return plain_text


plain_text = decode_uu_charset("02&DA($AO=R!A<F4@>6]U/P``")
print(plain_text)

You should read

Hi! How are you?

.