1.1.1 • Published 2 years ago

base62-token v1.1.1

Weekly downloads
-
License
SEE LICENSE IN LI...
Repository
github
Last release
2 years ago

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
PrefixEntropyChecksum
pre_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxcccccc

See

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

1.1.1

2 years ago

1.1.0

2 years ago

1.0.0

2 years ago