base64.py (5805B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\carbon\common\stdlib\base64.py 2 import re 3 import struct 4 import binascii 5 __all__ = ['encode', 6 'decode', 7 'encodestring', 8 'decodestring', 9 'b64encode', 10 'b64decode', 11 'b32encode', 12 'b32decode', 13 'b16encode', 14 'b16decode', 15 'standard_b64encode', 16 'standard_b64decode', 17 'urlsafe_b64encode', 18 'urlsafe_b64decode'] 19 _translation = [ chr(_x) for _x in range(256) ] 20 EMPTYSTRING = '' 21 22 def _translate(s, altchars): 23 translation = _translation[:] 24 for k, v in altchars.items(): 25 translation[ord(k)] = v 26 27 return s.translate(''.join(translation)) 28 29 30 def b64encode(s, altchars = None): 31 encoded = binascii.b2a_base64(s)[:-1] 32 if altchars is not None: 33 return _translate(encoded, {'+': altchars[0], 34 '/': altchars[1]}) 35 return encoded 36 37 38 def b64decode(s, altchars = None): 39 if altchars is not None: 40 s = _translate(s, {altchars[0]: '+', 41 altchars[1]: '/'}) 42 try: 43 return binascii.a2b_base64(s) 44 except binascii.Error as msg: 45 raise TypeError(msg) 46 47 48 def standard_b64encode(s): 49 return b64encode(s) 50 51 52 def standard_b64decode(s): 53 return b64decode(s) 54 55 56 def urlsafe_b64encode(s): 57 return b64encode(s, '-_') 58 59 60 def urlsafe_b64decode(s): 61 return b64decode(s, '-_') 62 63 64 _b32alphabet = {0: 'A', 65 9: 'J', 66 18: 'S', 67 27: '3', 68 1: 'B', 69 10: 'K', 70 19: 'T', 71 28: '4', 72 2: 'C', 73 11: 'L', 74 20: 'U', 75 29: '5', 76 3: 'D', 77 12: 'M', 78 21: 'V', 79 30: '6', 80 4: 'E', 81 13: 'N', 82 22: 'W', 83 31: '7', 84 5: 'F', 85 14: 'O', 86 23: 'X', 87 6: 'G', 88 15: 'P', 89 24: 'Y', 90 7: 'H', 91 16: 'Q', 92 25: 'Z', 93 8: 'I', 94 17: 'R', 95 26: '2'} 96 _b32tab = _b32alphabet.items() 97 _b32tab.sort() 98 _b32tab = [ v for k, v in _b32tab ] 99 _b32rev = dict([ (v, long(k)) for k, v in _b32alphabet.items() ]) 100 101 def b32encode(s): 102 parts = [] 103 quanta, leftover = divmod(len(s), 5) 104 if leftover: 105 s += '\x00' * (5 - leftover) 106 quanta += 1 107 for i in range(quanta): 108 c1, c2, c3 = struct.unpack('!HHB', s[i * 5:(i + 1) * 5]) 109 c2 += (c1 & 1) << 16 110 c3 += (c2 & 3) << 8 111 parts.extend([_b32tab[c1 >> 11], 112 _b32tab[c1 >> 6 & 31], 113 _b32tab[c1 >> 1 & 31], 114 _b32tab[c2 >> 12], 115 _b32tab[c2 >> 7 & 31], 116 _b32tab[c2 >> 2 & 31], 117 _b32tab[c3 >> 5], 118 _b32tab[c3 & 31]]) 119 120 encoded = EMPTYSTRING.join(parts) 121 if leftover == 1: 122 return encoded[:-6] + '======' 123 if leftover == 2: 124 return encoded[:-4] + '====' 125 if leftover == 3: 126 return encoded[:-3] + '===' 127 if leftover == 4: 128 return encoded[:-1] + '=' 129 return encoded 130 131 132 def b32decode(s, casefold = False, map01 = None): 133 quanta, leftover = divmod(len(s), 8) 134 if leftover: 135 raise TypeError('Incorrect padding') 136 if map01: 137 s = _translate(s, {'0': 'O', 138 '1': map01}) 139 if casefold: 140 s = s.upper() 141 padchars = 0 142 mo = re.search('(?P<pad>[=]*)$', s) 143 if mo: 144 padchars = len(mo.group('pad')) 145 if padchars > 0: 146 s = s[:-padchars] 147 parts = [] 148 acc = 0 149 shift = 35 150 for c in s: 151 val = _b32rev.get(c) 152 if val is None: 153 raise TypeError('Non-base32 digit found') 154 acc += _b32rev[c] << shift 155 shift -= 5 156 if shift < 0: 157 parts.append(binascii.unhexlify('%010x' % acc)) 158 acc = 0 159 shift = 35 160 161 last = binascii.unhexlify('%010x' % acc) 162 if padchars == 0: 163 last = '' 164 elif padchars == 1: 165 last = last[:-1] 166 elif padchars == 3: 167 last = last[:-2] 168 elif padchars == 4: 169 last = last[:-3] 170 elif padchars == 6: 171 last = last[:-4] 172 else: 173 raise TypeError('Incorrect padding') 174 parts.append(last) 175 return EMPTYSTRING.join(parts) 176 177 178 def b16encode(s): 179 return binascii.hexlify(s).upper() 180 181 182 def b16decode(s, casefold = False): 183 if casefold: 184 s = s.upper() 185 if re.search('[^0-9A-F]', s): 186 raise TypeError('Non-base16 digit found') 187 return binascii.unhexlify(s) 188 189 190 MAXLINESIZE = 76 191 MAXBINSIZE = MAXLINESIZE // 4 * 3 192 193 def encode(input, output): 194 while True: 195 s = input.read(MAXBINSIZE) 196 if not s: 197 break 198 while len(s) < MAXBINSIZE: 199 ns = input.read(MAXBINSIZE - len(s)) 200 if not ns: 201 break 202 s += ns 203 204 line = binascii.b2a_base64(s) 205 output.write(line) 206 207 208 def decode(input, output): 209 while True: 210 line = input.readline() 211 if not line: 212 break 213 s = binascii.a2b_base64(line) 214 output.write(s) 215 216 217 def encodestring(s): 218 pieces = [] 219 for i in range(0, len(s), MAXBINSIZE): 220 chunk = s[i:i + MAXBINSIZE] 221 pieces.append(binascii.b2a_base64(chunk)) 222 223 return ''.join(pieces) 224 225 226 def decodestring(s): 227 return binascii.a2b_base64(s) 228 229 230 def test(): 231 import sys, getopt 232 try: 233 opts, args = getopt.getopt(sys.argv[1:], 'deut') 234 except getopt.error as msg: 235 sys.stdout = sys.stderr 236 print msg 237 print "usage: %s [-d|-e|-u|-t] [file|-]\n -d, -u: decode\n -e: encode (default)\n -t: encode and decode string 'Aladdin:open sesame'" % sys.argv[0] 238 sys.exit(2) 239 240 func = encode 241 for o, a in opts: 242 if o == '-e': 243 func = encode 244 if o == '-d': 245 func = decode 246 if o == '-u': 247 func = decode 248 if o == '-t': 249 test1() 250 return 251 252 if args and args[0] != '-': 253 with open(args[0], 'rb') as f: 254 func(f, sys.stdout) 255 else: 256 func(sys.stdin, sys.stdout) 257 258 259 def test1(): 260 s0 = 'Aladdin:open sesame' 261 s1 = encodestring(s0) 262 s2 = decodestring(s1) 263 print s0, repr(s1), s2 264 265 266 if __name__ == '__main__': 267 test()