Package Exports
- base62-token
- base62-token/base62-token.js
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (base62-token) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
base62-token.js
Generate & Verify GitHub-style & npm-style Base62 Tokens
Works in Vanilla JS (Browsers), Node.js, and Webpack.
Online Demo
See the online Base62 token generator & verifier in action:
Install
Browser
<script src="https://unpkg.com/crc-32"></script>
<script src="https://unpkg.com/base62-token"></script>
var Base62Token = window.Base62Token;
Node.js / Webpack
npm install --save base62-token
var Base62Token = require("base62-token");
Usage
var dict = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
var b62Token = Base62Token.create(dict);
var token = b62Token.generate("abc_", 30);
var verified = b62Token.verify(token);
API
Base62Token.generateDictionary(); // Return the Lexographic (a.k.a. GMP)
// Base62 dictionary.
Base62Token.create(dictionary); // Creates a token generator and verifier
// 'dictionary' is any 62-char alphabet.
// Returns a generator / verifier instance.
b62Token.generate(prefix, length); // Returns token string.
b62Token.verify(token); // Returns true / false.
Base62Token.BITS_PER_CHARACTER // 5.954196310386876
// For reference: Base64 is an even 6
Base62Token.calcMinChars(bitlen); // calculate the minimum number of chars
// needed to guarantee the target entropy.
// ex: 173-bit entropy needs 30 chars
Base62Token.calcMinBits(charlen); // calculate the minimum entropy guaranteed
// by the given number of characters
// ex: 30 chars guarantees 178-bit entropy.
Base62Token.checksum(dict, str); // generates an (unsigned) CRC-32 checksum
// for the given string (where each char is
// treated as a single byte).
// Returns the Base62 encoded unsigned int.
Base62Token.encode(dict, n, pad); // encode a 32-bit int (i.e. CRC-32 checksum)
// as Base62 in the given dictionary, with a
// default pad of 6 (guarantees 32-bits).
Base62 Token Spec
GitHub Token Breakdown
The 40-character tokens are broken down into 3 consecutive parts:
pre_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxcccccc
- Prefix: 4-char (ex:
ghx_
) - Entropy: 30-char (178-bits + leading 0 padding)
BITS_PER_CHAR = Math.log(62) / Math.log(2) // about 5.9541
BITS_PER_CHAR * 30 // about 178.6258
- Checksum: 6-char CRC32 (32-bits, 4 bytes, 6 base62 characters)
- (of entropy-only, not prefix)
BITS_PER_CHAR * 5 // about 35.7251
Prefix | Entropy | Checksum |
---|---|---|
pre_ | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx | cccccc |
See
- https://github.blog/2021-04-05-behind-githubs-new-authentication-token-formats/
- https://github.blog/changelog/2021-09-23-npm-has-a-new-access-token-format/
Pseudocode
const DICT = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
const PREFIX_LEN = 4
const CHECKSUM_LEN = 6
func GenerateBase62Token(prefix string, len int) string {
entropy := []string{}
for 0..len {
index := math.RandomInt(62) // 0..61
char := DICT[index]
entropy = append(entropy, char)
}
chksum := crc32.Checksum(entropy) // uint32
pad := CHECKSUM_LEN
chksum62 := base62.Encode(DICT, chksum, pad)
// ex: "ghp_" + "zQWBuTSOoRi4A9spHcVY5ncnsDkxkJ" + "0mLq17"
return prefix + string(entropy) + chksum62
}
func VerifyBase62Token(token string) bool {
// prefix is not used
entropy := token[PREFIX_LEN:len(token)-CHECKSUM_LEN]
chksum := base62.Decode(DICT, token[len(token)-CHECKSUM_LEN:]) // uint32
return crc32.Checksum(entropy) == chksum
}
Standard Base62 Dictionaries
There are 3 widely-used, generic Base62 dictionaries, all of which are based on the alphanumeric character set (i.e. 0-9, A-Z, a-z).
For general encoding and decoding, you should use one of these:
- Lexographic (digits, upper, lower)
0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
- BaseX (digits, lower, upper)
0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
- Truncated Base64 (upper, lower, digits)
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789
GitHub and NPM use the Lexographic (a.k.a. GMP) Base62 alphabet.
Legal
For a business license and/or commercial support ($99/year), please contact Root.
Copyright 2022 AJ ONeal
Copyright 2022 Root
MPL-2.0 (Open Source) | Terms of Use | Privacy Policy