-
-
Notifications
You must be signed in to change notification settings - Fork 18
/
base32.ts
53 lines (46 loc) · 1.94 KB
/
base32.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
import { rfc4648 } from "../../deps.ts";
import { Base32String } from "../util/doc-types.ts";
import { ValidationError } from "../util/errors.ts";
const { codec } = rfc4648;
// For base32 encoding we use rfc4648, no padding, lowercase, prefixed with "b".
//
// Base32 character set: `abcdefghijklmnopqrstuvwxyz234567`
//
// The Multibase format adds a "b" prefix to specify this particular encoding.
// We leave the "b" prefix there because we don't want the encoded string
// to start with a number (so we can use it as a URL location).
//
// When decoding, we require it to start with a "b" --
// no other multibase formats are allowed.
//
// The decoding must be strict (it doesn't allow a 1 in place of an i, etc).
const myEncoding = {
// this should match b32chars from characters.ts
chars: "abcdefghijklmnopqrstuvwxyz234567",
bits: 5,
};
/** Encode uint8array bytes to base32 string */
export function base32BytesToString(bytes: Uint8Array): Base32String {
return "b" + codec.stringify(bytes, myEncoding, { pad: false });
}
/** Decode base32 string to a uint8array of bytes. Throw a ValidationError if the string is bad. */
export function base32StringToBytes(str: Base32String): Uint8Array {
if (!str.startsWith("b")) {
throw new ValidationError(
"can't decode base32 string - it should start with a 'b'. " + str,
);
}
// this library combines padding and looseness settings into a single "loose" option, so
// we have to set "loose: true" in order to handle unpadded inputs.
// with a custom codec, loose mode:
// -- allows padding or no padding -- we have to check for this
// -- does not allow uppercase -- good
// -- does not allow 1/i substitution -- good
// make sure no padding characters are on the end
if (str[str.length - 1] === "=") {
throw new ValidationError(
"can't decode base32 string - it contains padding characters ('=')",
);
}
return codec.parse(str.slice(1), myEncoding, { loose: true });
}