diff options
Diffstat (limited to 'std/encoding/base64.ts')
-rw-r--r-- | std/encoding/base64.ts | 78 |
1 files changed, 48 insertions, 30 deletions
diff --git a/std/encoding/base64.ts b/std/encoding/base64.ts index 4c9aa4059..e631e5b88 100644 --- a/std/encoding/base64.ts +++ b/std/encoding/base64.ts @@ -1,41 +1,59 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -/** - * Converts given data with base64 encoding - * @param data input to encode - */ -export function encode(data: string | ArrayBuffer): string { - if (typeof data === "string") { - return btoa(data); - } else { - const d = new Uint8Array(data); - let dataString = ""; - for (let i = 0; i < d.length; ++i) { - dataString += String.fromCharCode(d[i]); - } - - return btoa(dataString); - } -} +// deno-fmt-ignore +const base64abc = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", + "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "a", + "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", + "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "0", "1", "2", "3", "4", + "5", "6", "7", "8", "9", "+", "/"]; /** - * Converts given base64 encoded data back to original - * @param data input to decode + * CREDIT: https://gist.github.com/enepomnyaschih/72c423f727d395eeaa09697058238727 + * Encodes a given Uint8Array, ArrayBuffer or string into RFC4648 base64 representation + * @param data */ -export function decode(data: string): ArrayBuffer { - const binaryString = decodeString(data); - const binary = new Uint8Array(binaryString.length); - for (let i = 0; i < binary.length; ++i) { - binary[i] = binaryString.charCodeAt(i); +export function encode(data: ArrayBuffer | string): string { + const uint8 = + typeof data === "string" + ? new TextEncoder().encode(data) + : data instanceof Uint8Array + ? data + : new Uint8Array(data); + let result = "", + i; + const l = uint8.length; + for (i = 2; i < l; i += 3) { + result += base64abc[uint8[i - 2] >> 2]; + result += base64abc[((uint8[i - 2] & 0x03) << 4) | (uint8[i - 1] >> 4)]; + result += base64abc[((uint8[i - 1] & 0x0f) << 2) | (uint8[i] >> 6)]; + result += base64abc[uint8[i] & 0x3f]; } - - return binary.buffer; + if (i === l + 1) { + // 1 octet yet to write + result += base64abc[uint8[i - 2] >> 2]; + result += base64abc[(uint8[i - 2] & 0x03) << 4]; + result += "=="; + } + if (i === l) { + // 2 octets yet to write + result += base64abc[uint8[i - 2] >> 2]; + result += base64abc[((uint8[i - 2] & 0x03) << 4) | (uint8[i - 1] >> 4)]; + result += base64abc[(uint8[i - 1] & 0x0f) << 2]; + result += "="; + } + return result; } /** - * Decodes data assuming the output is in string type - * @param data input to decode + * Decodes a given RFC4648 base64 encoded string + * @param b64 */ -export function decodeString(data: string): string { - return atob(data); +export function decode(b64: string): Uint8Array { + const binString = atob(b64); + const size = binString.length; + const bytes = new Uint8Array(size); + for (let i = 0; i < size; i++) { + bytes[i] = binString.charCodeAt(i); + } + return bytes; } |