Path: blob/main/python/pylang/src/lib/encodings.py
1398 views
# vim:fileencoding=utf-81# License: BSD Copyright: 2016, Kovid Goyal <kovid at kovidgoyal.net>23def base64encode(bytes, altchars, pad_char):4# Convert an array of bytes into a base-64 encoded string5l = bytes.length6remainder = l % 37main_length = l - remainder8encodings = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789' + (altchars or '+/')9pad_char = '=' if pad_char is undefined else pad_char10ans = v'[]'11for v'var i = 0; i < main_length; i += 3':12chunk = (bytes[i] << 16) | (bytes[i + 1] << 8) | bytes[i + 2]13ans.push(encodings[(chunk & 16515072) >> 18], encodings[(chunk & 258048) >> 12], encodings[(chunk & 4032) >> 6], encodings[chunk & 63])14if remainder is 1:15chunk = bytes[main_length]16ans.push(encodings[(chunk & 252) >> 2], encodings[(chunk & 3) << 4], pad_char, pad_char)17elif remainder is 2:18chunk = (bytes[main_length] << 8) | bytes[main_length + 1]19ans.push(encodings[(chunk & 64512) >> 10], encodings[(chunk & 1008) >> 4], encodings[(chunk & 15) << 2], pad_char)20return ans.join('')2122def base64decode(string):23# convert the output of base64encode back into an array of bytes24# (Uint8Array) only works with the standard altchars and pad_char25if jstype(window) is not 'undefined':26chars = window.atob(string)27else:28chars = new Buffer(string, 'base64').toString('binary') # noqa: undef29ans = Uint8Array(chars.length)30for i in range(ans.length):31ans[i] = chars.charCodeAt(i)32return ans3334def urlsafe_b64encode(bytes, pad_char):35return base64encode(bytes, '-_', pad_char)3637def urlsafe_b64decode(string):38string = String.prototype.replace.call(string, /[_-]/g, def(m): return '+' if m is '-' else '/';)39return base64decode(string)4041def hexlify(bytes):42ans = v'[]'43for v'var i = 0; i < bytes.length; i++':44x = bytes[i].toString(16)45if x.length is 1:46x = '0' + x47ans.push(x)48return ans.join('')4950def unhexlify(string):51num = string.length // 252if num * 2 is not string.length:53raise ValueError('string length is not a multiple of two')54ans = Uint8Array(num)55for v'var i = 0; i < num; i++':56x = parseInt(string[i*2:i*2+2], 16)57if isNaN(x):58raise ValueError('string is not hex-encoded')59ans[i] = x60return ans6162utf8_decoder_table = v'''[630,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 00..1f640,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 20..3f650,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 40..5f660,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 60..7f671,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, // 80..9f687,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, // a0..bf698,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // c0..df700xa,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x4,0x3,0x3, // e0..ef710xb,0x6,0x6,0x6,0x5,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8, // f0..ff720x0,0x1,0x2,0x3,0x5,0x8,0x7,0x1,0x1,0x1,0x4,0x6,0x1,0x1,0x1,0x1, // s0..s0731,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,0,1,0,1,1,1,1,1,1, // s1..s2741,2,1,1,1,1,1,2,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1, // s3..s4751,2,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,3,1,1,1,1,1,1, // s5..s6761,3,1,1,1,1,1,3,1,3,1,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // s7..s877]'''7879def _from_code_point(x):80if x <= 0xFFFF:81return String.fromCharCode(x)82x -= 0x1000083return String.fromCharCode((x >> 10) + 0xD800, (x % 0x400) + 0xDC00)8485def utf8_decode(bytes, errors, replacement):86# Convert an array of UTF-8 encoded bytes into a string87state = 088ans = v'[]'8990for v'var i = 0, l = bytes.length; i < l; i++': # noqa91byte = bytes[i]92typ = utf8_decoder_table[byte]93codep = (byte & 0x3f) | (codep << 6) if state is not 0 else (0xff >> typ) & (byte)94state = utf8_decoder_table[256 + state*16 + typ]95if state is 0:96ans.push(_from_code_point(codep))97elif state is 1:98if not errors or errors is 'strict':99raise UnicodeDecodeError(str.format('The byte 0x{:02x} at position {} is not valid UTF-8', byte, i))100elif errors is 'replace':101ans.push(replacement or '?')102return ans.join('')103104def utf8_encode_js(string):105# Encode a string as an array of UTF-8 bytes106escstr = encodeURIComponent(string)107ans = v'[]'108for v'var i = 0; i < escstr.length; i++':109ch = escstr[i]110if ch is '%':111ans.push(parseInt(escstr[i+1:i+3], 16))112i += 2113else:114ans.push(ch.charCodeAt(0))115return Uint8Array(ans)116117if jstype(TextEncoder) is 'function':118_u8enc = TextEncoder('utf-8')119utf8_encode = _u8enc.encode.bind(_u8enc)120_u8enc = undefined121else:122utf8_encode = utf8_encode_js123124def utf8_encode_native(string):125return _u8enc.encode(string)126127128