-
Notifications
You must be signed in to change notification settings - Fork 636
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(encoding/unstable): Crockford base32 unstable support (#6238)
- Loading branch information
1 parent
31b3cd7
commit b2b7f99
Showing
3 changed files
with
143 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. | ||
// Copyright (c) 2014 Jameson Little. MIT License. | ||
// This module is browser compatible. | ||
|
||
/** | ||
* Utilities for | ||
* {@link https://www.crockford.com/base32.html | Crockford base32} | ||
* encoding and decoding. | ||
* | ||
* Modified from @std/encoding/base32. | ||
* | ||
* ```ts | ||
* import { encodeBase32Crockford, decodeBase32Crockford } from "@std/encoding/unstable-base32crockford"; | ||
* import { assertEquals } from "@std/assert"; | ||
* | ||
* assertEquals(encodeBase32Crockford("foobar"), "CSQPYRK1E8======"); | ||
* | ||
* assertEquals( | ||
* decodeBase32Crockford("CSQPYRK1E8======"), | ||
* new TextEncoder().encode("foobar") | ||
* ); | ||
* ``` | ||
* | ||
* @module | ||
*/ | ||
import { decode, encode } from "./_base32_common.ts"; | ||
|
||
const lookup: string[] = "0123456789ABCDEFGHJKMNPQRSTVWXYZ".split(""); | ||
const revLookup: number[] = []; | ||
lookup.forEach((c, i) => (revLookup[c.charCodeAt(0)] = i)); | ||
|
||
/** | ||
* Decodes a Crockford base32-encoded string. | ||
* | ||
* @see {@link https://www.crockford.com/base32.html} | ||
* | ||
* @param b32 The Crockford Base32-encoded string to decode. | ||
* @returns The decoded data. | ||
* | ||
* @example Usage | ||
* ```ts | ||
* import { decodeBase32Crockford } from "@std/encoding/unstable-base32crockford"; | ||
* import { assertEquals } from "@std/assert"; | ||
* | ||
* assertEquals( | ||
* decodeBase32Crockford("CSQPYRK1E8======"), | ||
* new TextEncoder().encode("foobar") | ||
* ); | ||
* ``` | ||
*/ | ||
export function decodeBase32Crockford(b32: string): Uint8Array { | ||
return decode(b32, lookup); | ||
} | ||
|
||
/** | ||
* Converts data into a Crockford base32-encoded string. | ||
* | ||
* @see {@link https://www.crockford.com/base32.html} | ||
* | ||
* @param data The data to encode. | ||
* @returns The Crockford base32-encoded string. | ||
* | ||
* @example Usage | ||
* ```ts | ||
* import { encodeBase32Crockford } from "@std/encoding/unstable-base32crockford"; | ||
* import { assertEquals } from "@std/assert"; | ||
* | ||
* assertEquals(encodeBase32Crockford("foobar"), "CSQPYRK1E8======"); | ||
* ``` | ||
*/ | ||
export function encodeBase32Crockford( | ||
data: ArrayBuffer | Uint8Array | string, | ||
): string { | ||
return encode(data, lookup); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
// Test cases copied from https://github.com/LinusU/base32-encode/blob/master/test.js | ||
// Copyright (c) 2016-2017 Linus Unnebäck. MIT license. | ||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. | ||
import { assertEquals, assertExists, assertThrows } from "@std/assert"; | ||
import { | ||
decodeBase32Crockford, | ||
encodeBase32Crockford, | ||
} from "./unstable_base32crockford.ts"; | ||
|
||
// Test vectors from https://www.rfc-editor.org/rfc/rfc4648.html#section-10 | ||
const testCases = [ | ||
["", ""], | ||
["f", "CR======"], | ||
["fo", "CSQG===="], | ||
["foo", "CSQPY==="], | ||
["foob", "CSQPYRG="], | ||
["fooba", "CSQPYRK1"], | ||
["foobar", "CSQPYRK1E8======"], | ||
] as const; | ||
|
||
Deno.test({ | ||
name: "encodeBase32()", | ||
fn() { | ||
for (const [bin, b32] of testCases) { | ||
assertEquals(encodeBase32Crockford(bin), b32); | ||
} | ||
}, | ||
}); | ||
|
||
Deno.test({ | ||
name: "decodeBase32()", | ||
fn() { | ||
for (const [bin, b32] of testCases) { | ||
assertEquals(decodeBase32Crockford(b32), new TextEncoder().encode(bin)); | ||
} | ||
}, | ||
}); | ||
|
||
Deno.test({ | ||
name: "decodeBase32() throws on bad length", | ||
fn() { | ||
assertThrows( | ||
() => decodeBase32Crockford("OOOO=="), | ||
Error, | ||
"Cannot decode base32 string as the length must be a multiple of 8: received length 6", | ||
); | ||
}, | ||
}); | ||
|
||
Deno.test({ | ||
name: "decodeBase32() throws on bad padding", | ||
fn() { | ||
assertThrows( | ||
() => decodeBase32Crockford("5HXR334AQYAAAA=="), | ||
Error, | ||
"Invalid pad length", | ||
); | ||
}, | ||
}); | ||
|
||
Deno.test({ | ||
name: "encodeBase32() encodes very long text", | ||
fn() { | ||
const data = "a".repeat(16400); | ||
assertExists(encodeBase32Crockford(data)); | ||
}, | ||
}); |