Files

240 lines
5.5 KiB
JavaScript

export function encodeBase64(bytes) {
return encodeBase64_internal(bytes, base64Alphabet, EncodingPadding.Include);
}
export function encodeBase64NoPadding(bytes) {
return encodeBase64_internal(bytes, base64Alphabet, EncodingPadding.None);
}
export function encodeBase64url(bytes) {
return encodeBase64_internal(bytes, base64urlAlphabet, EncodingPadding.Include);
}
export function encodeBase64urlNoPadding(bytes) {
return encodeBase64_internal(bytes, base64urlAlphabet, EncodingPadding.None);
}
function encodeBase64_internal(bytes, alphabet, padding) {
let result = "";
for (let i = 0; i < bytes.byteLength; i += 3) {
let buffer = 0;
let bufferBitSize = 0;
for (let j = 0; j < 3 && i + j < bytes.byteLength; j++) {
buffer = (buffer << 8) | bytes[i + j];
bufferBitSize += 8;
}
for (let j = 0; j < 4; j++) {
if (bufferBitSize >= 6) {
result += alphabet[(buffer >> (bufferBitSize - 6)) & 0x3f];
bufferBitSize -= 6;
}
else if (bufferBitSize > 0) {
result += alphabet[(buffer << (6 - bufferBitSize)) & 0x3f];
bufferBitSize = 0;
}
else if (padding === EncodingPadding.Include) {
result += "=";
}
}
}
return result;
}
const base64Alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
const base64urlAlphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
export function decodeBase64(encoded) {
return decodeBase64_internal(encoded, base64DecodeMap, DecodingPadding.Required);
}
export function decodeBase64IgnorePadding(encoded) {
return decodeBase64_internal(encoded, base64DecodeMap, DecodingPadding.Ignore);
}
export function decodeBase64url(encoded) {
return decodeBase64_internal(encoded, base64urlDecodeMap, DecodingPadding.Required);
}
export function decodeBase64urlIgnorePadding(encoded) {
return decodeBase64_internal(encoded, base64urlDecodeMap, DecodingPadding.Ignore);
}
function decodeBase64_internal(encoded, decodeMap, padding) {
const result = new Uint8Array(Math.ceil(encoded.length / 4) * 3);
let totalBytes = 0;
for (let i = 0; i < encoded.length; i += 4) {
let chunk = 0;
let bitsRead = 0;
for (let j = 0; j < 4; j++) {
if (padding === DecodingPadding.Required && encoded[i + j] === "=") {
continue;
}
if (padding === DecodingPadding.Ignore &&
(i + j >= encoded.length || encoded[i + j] === "=")) {
continue;
}
if (j > 0 && encoded[i + j - 1] === "=") {
throw new Error("Invalid padding");
}
if (!(encoded[i + j] in decodeMap)) {
throw new Error("Invalid character");
}
chunk |= decodeMap[encoded[i + j]] << ((3 - j) * 6);
bitsRead += 6;
}
if (bitsRead < 24) {
let unused;
if (bitsRead === 12) {
unused = chunk & 0xffff;
}
else if (bitsRead === 18) {
unused = chunk & 0xff;
}
else {
throw new Error("Invalid padding");
}
if (unused !== 0) {
throw new Error("Invalid padding");
}
}
const byteLength = Math.floor(bitsRead / 8);
for (let i = 0; i < byteLength; i++) {
result[totalBytes] = (chunk >> (16 - i * 8)) & 0xff;
totalBytes++;
}
}
return result.slice(0, totalBytes);
}
var EncodingPadding;
(function (EncodingPadding) {
EncodingPadding[EncodingPadding["Include"] = 0] = "Include";
EncodingPadding[EncodingPadding["None"] = 1] = "None";
})(EncodingPadding || (EncodingPadding = {}));
var DecodingPadding;
(function (DecodingPadding) {
DecodingPadding[DecodingPadding["Required"] = 0] = "Required";
DecodingPadding[DecodingPadding["Ignore"] = 1] = "Ignore";
})(DecodingPadding || (DecodingPadding = {}));
const base64DecodeMap = {
"0": 52,
"1": 53,
"2": 54,
"3": 55,
"4": 56,
"5": 57,
"6": 58,
"7": 59,
"8": 60,
"9": 61,
A: 0,
B: 1,
C: 2,
D: 3,
E: 4,
F: 5,
G: 6,
H: 7,
I: 8,
J: 9,
K: 10,
L: 11,
M: 12,
N: 13,
O: 14,
P: 15,
Q: 16,
R: 17,
S: 18,
T: 19,
U: 20,
V: 21,
W: 22,
X: 23,
Y: 24,
Z: 25,
a: 26,
b: 27,
c: 28,
d: 29,
e: 30,
f: 31,
g: 32,
h: 33,
i: 34,
j: 35,
k: 36,
l: 37,
m: 38,
n: 39,
o: 40,
p: 41,
q: 42,
r: 43,
s: 44,
t: 45,
u: 46,
v: 47,
w: 48,
x: 49,
y: 50,
z: 51,
"+": 62,
"/": 63
};
const base64urlDecodeMap = {
"0": 52,
"1": 53,
"2": 54,
"3": 55,
"4": 56,
"5": 57,
"6": 58,
"7": 59,
"8": 60,
"9": 61,
A: 0,
B: 1,
C: 2,
D: 3,
E: 4,
F: 5,
G: 6,
H: 7,
I: 8,
J: 9,
K: 10,
L: 11,
M: 12,
N: 13,
O: 14,
P: 15,
Q: 16,
R: 17,
S: 18,
T: 19,
U: 20,
V: 21,
W: 22,
X: 23,
Y: 24,
Z: 25,
a: 26,
b: 27,
c: 28,
d: 29,
e: 30,
f: 31,
g: 32,
h: 33,
i: 34,
j: 35,
k: 36,
l: 37,
m: 38,
n: 39,
o: 40,
p: 41,
q: 42,
r: 43,
s: 44,
t: 45,
u: 46,
v: 47,
w: 48,
x: 49,
y: 50,
z: 51,
"-": 62,
_: 63
};