Advertisement
ijontichy

b64test.py

Jul 16th, 2012
78
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.98 KB | None | 0 0
  1. import string
  2. import math
  3.  
  4. b64Chars = (string.ascii_uppercase + string.ascii_lowercase + string.digits + "+/").encode()
  5.  
  6. b64BackChars = \
  7. (
  8.     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  9.     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  10.     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
  11.     52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
  12.     -1, 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10, 11, 12, 13, 14,
  13.     15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
  14.     -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
  15.     41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1,
  16.     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  17.     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  18.     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  19.     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  20.     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  21.     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  22.     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  23.     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
  24. )
  25.  
  26. def b64_chunk(byteChunk):
  27.     byteChunk = byteChunk[:3]
  28.    
  29.     if len(byteChunk) == 3:    
  30.         ret = (
  31.                 byteChunk[0] >> 2,
  32.                 ((byteChunk[0] & 0x3) << 4) + (byteChunk[1] >> 4),
  33.                 ((byteChunk[1] & 0xF) << 2) + (byteChunk[2] >> 6),
  34.                 byteChunk[2] & 0x3F
  35.               )
  36.  
  37.     if len(byteChunk) == 2:
  38.         ret = (
  39.                 byteChunk[0] >> 2,
  40.                 ((byteChunk[0] & 0x3) << 4) + (byteChunk[1] >> 4),
  41.                 ((byteChunk[1] & 0xF) << 2),
  42.                 -1
  43.               )
  44.  
  45.     if len(byteChunk) == 1:
  46.         ret = (
  47.                 byteChunk[0] >> 2,
  48.                 ((byteChunk[0] & 0x3) << 4),
  49.                 -1,
  50.                 -1
  51.               )
  52.      
  53.     if len(byteChunk) == 0:
  54.         ret = (-1, -1, -1, -1)
  55.      
  56.     return ret
  57.  
  58.  
  59. def b64_strChunk(byteChunk):
  60.     byteChunk = b64_chunk(byteChunk)
  61.     ret = bytearray()
  62.    
  63.     for i in byteChunk[::-1]:
  64.         if i == -1:
  65.             ret += b'='
  66.         else:
  67.             ret += b64Chars[i:i+1]
  68.    
  69.     ret = ret[::-1]
  70.     return ret
  71.  
  72.  
  73. def b64_encode(byteStream):
  74.     ret = b''
  75.     for i in range(math.ceil(len(byteStream) / 3)):
  76.         i *= 3
  77.         ret += b64_strChunk(byteStream[i:i+3])
  78.  
  79.     return ret
  80.  
  81.  
  82.  
  83. def b64_unstring(b64Chunk):
  84.     ret = []
  85.  
  86.     for i in b64Chunk:
  87.         if i == b'='[0]:
  88.             ret.append(-1)
  89.         elif b64BackChars[i] == -1:
  90.             raise ValueError("\'{}\' not a valid base64 character".format(ord(i)))
  91.         else:
  92.             ret.append(b64BackChars[i])
  93.    
  94.     return ret
  95.  
  96.  
  97. def b64_unchunk(b64Chunk):
  98.     numChunk   = b64_unstring(b64Chunk)
  99.     padCount   = 0
  100.     padInvalid = 0
  101.  
  102.     ret = [-1] * 3
  103.  
  104.     for i in numChunk[::-1]:
  105.         if i == -1:
  106.             if padInvalid: raise ValueError("invalid padding for \"{}\"".format(b64Chunk.decode()))
  107.  
  108.             padCount += 1
  109.         else:
  110.             padInvalid = 1
  111.  
  112.     if padCount == 0:
  113.         ret[0] = (numChunk[0] << 2) + (numChunk[1] >> 4)
  114.         ret[1] = ((numChunk[1] & 0xF) << 4) + (numChunk[2] >> 2)
  115.         ret[2] = ((numChunk[2] & 0x3) << 6) + numChunk[3]
  116.  
  117.     if padCount == 1:
  118.         ret[0] = (numChunk[0] << 2) + (numChunk[1] >> 4)
  119.         ret[1] = ((numChunk[1] & 0xF) << 4) + (numChunk[2] >> 2)
  120.  
  121.     if padCount == 2:
  122.         ret[0] = (numChunk[0] << 2) + (numChunk[1] >> 4)
  123.  
  124.     if padCount == 3:
  125.         raise ValueError("invalid amount of padding")
  126.  
  127.     return ret
  128.  
  129.  
  130. def b64_strUnchunk(b64Chunk):
  131.     byteChunk = b64_unchunk(b64Chunk)
  132.     ret = bytearray()
  133.    
  134.     for i in byteChunk:
  135.         if i == -1:
  136.             break
  137.         else:
  138.             ret += bytes([i])
  139.    
  140.     return ret
  141.  
  142.  
  143. def b64_decode(b64Stream):
  144.     ret = b''
  145.     for i in range(math.ceil(len(b64Stream) / 4)):
  146.         i *= 4
  147.         ret += b64_strUnchunk(b64Stream[i:i+4])
  148.  
  149.     return ret
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement