]>
Lady’s Gitweb - Pisces/blob - base64.js
1 // ♓🌟 Piscēs ∷ base64.js
2 // ====================================================================
4 // Copyright © 2020–2022 Lady [@ Lady’s Computer].
6 // This Source Code Form is subject to the terms of the Mozilla Public
7 // License, v. 2.0. If a copy of the MPL was not distributed with this
8 // file, You can obtain one at <https://mozilla.org/MPL/2.0/>.
10 import { getPrototype
, hasOwnProperty
} from "./object.js";
13 * Returns an ArrayBuffer generated from the provided Base64.
15 * This function can also be used as a tag for a template literal. The
16 * literal will be interpreted akin to `String.raw`.
18 export const a2b
= ($, ...$s
) => {
22 : hasOwnProperty($, "raw")
23 ? String
.raw($, ...$s
)
25 ).replace(/[\t\n\f\r ]+/gu, "");
26 const u6s
= Array
.prototype.map
.call(
27 source
.length
% 4 == 0 ? source
.replace(/={1,2}$/u, "") : source
,
29 const code
= character
.charCodeAt(0);
30 const result
= code
>= 0x41 && code
<= 0x5A
32 : code
>= 0x61 && code
<= 0x7A
34 : code
>= 0x30 && code
<= 0x39
43 `Piscēs: Invalid character in Base64: ${character}.`,
50 const { length
} = u6s
;
51 const dataView
= new DataView(
52 new ArrayBuffer(Math
.floor(length
* 3 / 4)),
54 for (let index
= 0; index
< length
- 1;) {
55 const dataIndex
= Math
.ceil(index
* 3 / 4);
56 const remainder
= index
% 3;
60 (u6s
[index
] << 2) + (u6s
[++index
] >> 4),
62 } else if (remainder
== 1) {
65 ((u6s
[index
] & 0xF) << 4) + (u6s
[++index
] >> 2),
70 ((u6s
[index
] & 0x3) << 6) + u6s
[++index
],
74 return dataView
.buffer
;
78 * Returns a (big‐endian) base64 string created from a typed array,
81 * This function can also be used as a tag for a template literal. The
82 * literal will be interpreted akin to `String.raw`.
84 export const b2a
= ($, ...$s
) => {
85 const buffer
= $ instanceof ArrayBuffer
87 : $ instanceof DataView
|| $ instanceof getPrototype(Uint8Array
)
90 Array
.prototype.reduce
.call(
92 (result
, code
·point
, index
) => (
93 result
.setUint16(index
* 2, code
·point
.charCodeAt(0)), result
95 new DataView(new ArrayBuffer(string
.length
* 2)),
99 : Object
.hasOwn($, "raw")
100 ? String
.raw($, ...$s
)
103 const dataView
= new DataView(buffer
);
104 const { byteLength
} = buffer
;
105 const minimumLengthOfResults
= Math
.ceil(byteLength
* 4 / 3);
106 const resultingCode
·points
= new Array(
107 minimumLengthOfResults
+ (4 - (minimumLengthOfResults
% 4)) % 4,
109 for (let index
= 0; index
< byteLength
;) {
110 const code
·pointIndex
= Math
.ceil(index
* 4 / 3);
111 const currentIndex
= code
·pointIndex
+ +(
112 index
% 3 == 0 && resultingCode
·points
[code
·pointIndex
] != 0x3D
114 const remainder
= currentIndex
% 4;
115 const u6
= remainder
== 0
116 ? dataView
.getUint8(index
) >> 2
118 ? ((dataView
.getUint8(index
++) & 0x3) << 4) +
119 (index
< byteLength
? dataView
.getUint8(index
) >> 4 : 0)
121 ? ((dataView
.getUint8(index
++) & 0xF) << 2) +
122 (index
< byteLength
? dataView
.getUint8(index
) >> 6 : 0)
123 : dataView
.getUint8(index
++) & 0x3F;
124 const result
= u6
< 26
136 throw new RangeError(`Piscēs: Unexpected Base64 value: ${u6}.`);
138 resultingCode
·points
[currentIndex
] = result
;
141 return String
.fromCodePoint(...resultingCode
·points
);
145 * Returns whether the provided value is a Base64 string.
147 * Returns false if the provided value is not a string primitive.
149 export const isBase64
= ($) => {
150 if (typeof $ != "string") return false;
151 const source
= $.replace(/[\t\n\f\r ]+/gu, "");
152 const trimmed
= source
.length
% 4 == 0
153 ? source
.replace(/={1,2}$/u, "")
155 return trimmed
.length
% 4 != 1 &&
156 !/[^0-9A-Za-z+\/]/u.test(trimmed
);
This page took 0.121985 seconds and 5 git commands to generate.