@helios-lang/codec-utils
Advanced tools
Comparing version 0.1.10 to 0.1.11
{ | ||
"name": "@helios-lang/codec-utils", | ||
"version": "0.1.10", | ||
"version": "0.1.11", | ||
"description": "Primitive manipulation functions commonly used in encoding and decoding algorithms", | ||
@@ -5,0 +5,0 @@ "main": "src/index.js", |
/** | ||
* Checks if all the characters in `s` are in the given base32 alphabet. | ||
* Checks lengths if their pad characters at the end | ||
* @param {string} s | ||
* @param {string} padChar | ||
* @returns {boolean} | ||
*/ | ||
export function isValidBase32(s: string, alphabet?: string): boolean; | ||
export function isValidBase32(s: string, alphabet?: string, padChar?: string): boolean; | ||
/** | ||
@@ -20,3 +22,3 @@ * @param {number[]} bytes | ||
*/ | ||
export function encodeBase32(bytes: number[], alphabet?: string): string; | ||
export function encodeBase32(bytes: number[], alphabet?: string, padChar?: string): string; | ||
/** | ||
@@ -36,2 +38,8 @@ * Decodes a Base32 string into bytes. | ||
export const DEFAULT_BASE32_ALPHABET: string; | ||
/** | ||
* Rfc 4648. | ||
* Although the pad-char is technically redundant, it is still needed to adhere to the spec | ||
* @type {string} | ||
*/ | ||
export const DEFAULT_BASE32_PAD_CHAR: string; | ||
//# sourceMappingURL=base32.d.ts.map |
@@ -10,8 +10,63 @@ import { BitReader, BitWriter, padBits } from "../bits/index.js" | ||
/** | ||
* Rfc 4648. | ||
* Although the pad-char is technically redundant, it is still needed to adhere to the spec | ||
* @type {string} | ||
*/ | ||
export const DEFAULT_BASE32_PAD_CHAR = "=" | ||
/** | ||
* Checks if all the characters in `s` are in the given base32 alphabet. | ||
* Checks lengths if their pad characters at the end | ||
* @param {string} s | ||
* @param {string} padChar | ||
* @returns {boolean} | ||
*/ | ||
export function isValidBase32(s, alphabet = DEFAULT_BASE32_ALPHABET) { | ||
return s.split("").every((c) => alphabet.indexOf(c.toLowerCase()) >= 0) | ||
export function isValidBase32( | ||
s, | ||
alphabet = DEFAULT_BASE32_ALPHABET, | ||
padChar = DEFAULT_BASE32_PAD_CHAR | ||
) { | ||
let n = s.length | ||
if (s.endsWith(padChar)) { | ||
if (s.length % 8 != 0) { | ||
return false | ||
} | ||
const iPad = s.indexOf(padChar) | ||
for (let i = iPad + 1; i < n; i++) { | ||
if (s.at(i) != padChar) { | ||
return false | ||
} | ||
} | ||
const nPad = n - iPad | ||
if (nPad != 6 && nPad != 4 && nPad != 3 && nPad != 1) { | ||
return false | ||
} | ||
s = s.slice(0, iPad) | ||
n = iPad | ||
} | ||
// the last char can't be any possible number | ||
return s.split("").every((c, i) => { | ||
const code = alphabet.indexOf(c.toLowerCase()) | ||
if (code < 0) { | ||
return false | ||
} | ||
if (i == n - 1) { | ||
const nBitsExtra = n * 5 - Math.floor((n * 5) / 8) * 8 | ||
return (((1 << nBitsExtra) - 1) & code) == 0 | ||
} else { | ||
return true | ||
} | ||
}) | ||
} | ||
@@ -39,5 +94,26 @@ | ||
*/ | ||
function decodeBase32Raw(encoded, alphabet = DEFAULT_BASE32_ALPHABET) { | ||
const n = encoded.length | ||
function decodeBase32Raw( | ||
encoded, | ||
alphabet = DEFAULT_BASE32_ALPHABET, | ||
padChar = DEFAULT_BASE32_PAD_CHAR | ||
) { | ||
let n = encoded.length | ||
while (n >= 0 && encoded.at(n - 1) == padChar) { | ||
n -= 1 | ||
} | ||
// length alignment is only checked if there are some padding characters at the end | ||
if (n < encoded.length && encoded.length % 8 != 0) { | ||
throw new Error("invalid length (expected multiple of 8)") | ||
} | ||
const nPad = encoded.length - n | ||
if (nPad != 0) { | ||
if (nPad != 6 && nPad != 4 && nPad != 3 && nPad != 1) { | ||
throw new Error("invalid number of base32 padding characters") | ||
} | ||
} | ||
/** | ||
@@ -50,2 +126,7 @@ * @type {number[]} | ||
const c = encoded[i] | ||
if (c == padChar) { | ||
throw new Error("unexpected padding character") | ||
} | ||
const code = alphabet.indexOf(c.toLowerCase()) | ||
@@ -55,2 +136,8 @@ | ||
throw new Error(`invalid base32 character ${c}`) | ||
} else if (i == n - 1) { | ||
const nBitsExtra = n * 5 - Math.floor((n * 5) / 8) * 8 | ||
if ((((1 << nBitsExtra) - 1) & code) != 0) { | ||
throw new Error(`invalid base32 final character`) | ||
} | ||
} | ||
@@ -72,6 +159,18 @@ | ||
*/ | ||
export function encodeBase32(bytes, alphabet = DEFAULT_BASE32_ALPHABET) { | ||
return encodeBase32Raw(bytes) | ||
export function encodeBase32( | ||
bytes, | ||
alphabet = DEFAULT_BASE32_ALPHABET, | ||
padChar = DEFAULT_BASE32_PAD_CHAR | ||
) { | ||
const s = encodeBase32Raw(bytes) | ||
.map((c) => alphabet[c]) | ||
.join("") | ||
const n = s.length | ||
if (n % 8 != 0 && padChar != "") { | ||
return s + new Array(8 - (n % 8)).fill(padChar).join("") | ||
} else { | ||
return s | ||
} | ||
} | ||
@@ -90,5 +189,7 @@ | ||
const n = encoded.length | ||
const raw = decodeBase32Raw(encoded, alphabet) | ||
decodeBase32Raw(encoded, alphabet).forEach((code, i) => { | ||
const n = raw.length | ||
raw.forEach((code, i) => { | ||
if (i == n - 1) { | ||
@@ -95,0 +196,0 @@ // last, make sure we align to byte |
export { ByteStream } from "./ByteStream.js"; | ||
export { bytesToHex, hexToBytes } from "./base16.js"; | ||
export { DEFAULT_BASE32_ALPHABET, decodeBase32, encodeBase32, encodeBase32Raw, isValidBase32 } from "./base32.js"; | ||
export { decodeBase64, encodeBase64, isValidBase64 } from "./base64.js"; | ||
export { padBytes, compareBytes } from "./ops.js"; | ||
//# sourceMappingURL=index.d.ts.map |
@@ -10,2 +10,3 @@ export { ByteStream } from "./ByteStream.js" | ||
} from "./base32.js" | ||
export { decodeBase64, encodeBase64, isValidBase64 } from "./base64.js" | ||
export { padBytes, compareBytes } from "./ops.js" |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
53865
60
1626