Commit 251ed373 authored by Adrian Buchholz's avatar Adrian Buchholz

works now.

parent e6b8147f
class Base64Converter:
def __init__(self):
self.d = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
self.dg = {}
for pos, dig in enumerate(self.d):
self.dg[dig] = pos
def encode(self, f):
s = ''
data = f.read(3)
......@@ -13,15 +16,16 @@ class Base64Converter:
return s
def decode(self, f):
digits = {}
for pos, digit in enumerate(self.d):
digits[digit] = pos
bs = ''
self.dg = {}
for pos, dig in enumerate(self.d):
self.dg[dig] = pos
bs = bytes()
data = f.read(4)
while data:
bs += self.decode4chars(data, digits)
bs += self.decode4chars(data)
data = f.read(4)
return bs
......@@ -54,26 +58,26 @@ class Base64Converter:
return f'{d[index1]}{d[index2]}{d[index3]}{d[index4]}'
def decode4chars(self, s, d):
def decode4chars(self, s):
if not isinstance(s, str) or len(s) != 4 or \
not all([ch in self.d for ch in s[:2]]) or \
not all([ch in self.d + '=' for ch in s[2:]]):
raise ValueError(f'{s} is not a base64 encoded string')
int1 = d[s[0]]
int2 = d[s[1]]
int1 = self.dg[s[0]]
int2 = self.dg[s[1]]
b1 = (int1 << 2) | ((int2 & 48) >> 4)
if s[2:] == '==':
return bytes([b1])
int3 = d[s[2]]
int3 = self.dg[s[2]]
b2 = (int2 & 15) << 4 | int3 >> 2
if s[3:] == '=':
return bytes([b1, b2])
int4 = d[s[3]]
int4 = self.dg[s[3]]
b3 = (int3 & 3) << 6 | int4
return bytes([b1, b2, b3])
......@@ -60,7 +60,7 @@ which in Hex is 49338F, and we have our test.
The inverse adds another twist, which is that when a byte can be represented
by a printable ASCII character, that is how Python represents it by default:
>>> b64.decode4chars('STOP', {'S':18, 'T':19, 'O':14, 'P':15})
>>> b64.decode4chars('STOP')
b'I3\x8f'
A very helpful resource for working with binary data in Python is:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment