Hashing and Unique IDs

Utility functions for generating consistent hashes and converting numbers to different bases. Useful for creating unique identifiers, keys, and compact representations.

hash

Generates a numeric hash from a string. The hash is deterministic - the same input always produces the same output.

Signature

function hash(source: string, modulus?: number): number

Parameters

ParameterTypeDefaultDescription
sourcestringRequiredThe string to hash
modulusnumber-Optional modulus to constrain the hash range

Returns

A non-negative integer hash value.

Basic usage

import { hash } from "aidos-ui";

const id = hash("ABC");        // 64578
const id2 = hash("ABC");       // 64578 (same input = same output)
const id3 = hash("ABCD");      // Different value

With modulus

Constrain the hash to a specific range:

// Hash constrained to 0-9
const small_id = hash("ABC", 10);  // 8

// Hash constrained to 0-99
const medium_id = hash("ABC", 100);  // 78

// Useful for array indices
const colors = ["red", "blue", "green", "yellow"];
const colorIndex = hash("user123", colors.length);
const userColor = colors[colorIndex];

Use cases

// Consistent avatar colors
function getUserColor(userId) {
  const colors = ["#FF5733", "#33FF57", "#3357FF", "#FF33F5"];
  return colors[hash(userId, colors.length)];
}

// Cache keys
const cacheKey = hash(JSON.stringify(params));

// Partitioning
const partition = hash(userId, 10);  // 0-9

numberToBase

Converts a number to a string representation in an arbitrary base using custom characters.

Signature

function numberToBase(
  value: number,
  alphabet?: string[]
): string

Parameters

ParameterTypeDefaultDescription
valuenumberRequiredThe number to convert
alphabetstring[]["a"-"z"]Characters to use for each digit

Returns

A string representation of the number in the given base.

Basic usage

import { numberToBase } from "aidos-ui";

// Default: base-26 using lowercase letters
const id = numberToBase(hash("ABC"));  // "cqmv"
const id2 = numberToBase(12345);       // "wmt"

Custom bases

// Binary (base-2)
numberToBase(8, ["0", "1"]);           // "1000"

// With custom symbols
numberToBase(hash("ABC"), ["?", "!"]);  // "!!!!!???!???!?!"

// Hexadecimal-like
const hex = ["0", "1", "2", "3", "4", "5", "6", "7",
             "8", "9", "a", "b", "c", "d", "e", "f"];
numberToBase(255, hex);                 // "ff"

// URL-safe characters
const urlSafe = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".split("");
numberToBase(123456789, urlSafe);       // Compact URL-safe ID

Combining with hash

// Generate compact, unique IDs
function generateId(input) {
  return numberToBase(hash(input));
}

const userId = generateId("user@example.com");  // e.g., "xkcd"
const postId = generateId("blog-post-title");   // e.g., "qwer"

Common patterns

Unique class names

function uniqueClassName(styles) {
  const styleString = JSON.stringify(styles);
  return `_${numberToBase(hash(styleString))}`;
}

const className = uniqueClassName({ color: "red" });  // e.g., "_abc"

Consistent randomization

// Same input always gives same "random" result
function pseudoRandom(seed, max) {
  return hash(seed, max);
}

// Consistent shuffle based on seed
function seededShuffle(array, seed) {
  return array.slice().sort((a, b) => {
    return hash(`${seed}-${a}`) - hash(`${seed}-${b}`);
  });
}

Short URLs

// Convert database IDs to short codes
function toShortCode(numericId) {
  const chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".split("");
  return numberToBase(numericId, chars);
}

toShortCode(123456);  // e.g., "w7e"

Color from string

function stringToColor(str) {
  const h = hash(str, 360);
  return `hsl(${h}, 70%, 50%)`;
}

stringToColor("John");   // Consistent color for "John"
stringToColor("Jane");   // Different color for "Jane"

Algorithm details

The hash function uses a simple but effective string hashing algorithm:

  • Iterates through each character
  • Combines character codes using bit shifting
  • Produces a 32-bit integer hash
  • Applies modulus if specified

This is suitable for:

  • Generating consistent keys
  • Distributing values evenly
  • Creating pseudo-random but reproducible results

Not suitable for:

  • Cryptographic purposes
  • Security-sensitive hashing
  • Password storage