Mehr Unique ID (MUID)
64-bit BigInt database IDs, Base36 case-insensitive identifiers, and 256-bit Base62 account authentication tokens.
MUID Specification
Technical architecture, Tehran epoch offset, numeric BigInt representation, and token security parameters.
1. Epoch & Numeric ID
Generated sequentially from the fixed Tehran epoch with 4 random digits:
- Epoch:
2026-09-22 00:00:00 (UTC+3:30)=1790022600sec - Formula:
RawBigInt = (ElapsedSec * 10000) + Random(0..9999) - Database: Stored as native 64-bit
BIGINT - Vectors:
13954201234→6eryyky|390889398→6gq46u
2. Secret & API Regex
256-bit security hash and standardized authorization token regex:
- Secret: 32 CSPRNG bytes in Base62 (43 alphanumeric chars)
- Token:
"<account id>:<account secret>"
The Genesis Epoch Decision (Why 2026-09-22?)
Day 0 OffsetThe first day of Mehr being released was 2026-09-23 (which corresponds to 2585-07-01, or 1 Mehr 2585). MUID starts exactly one day before the release date to anchor the timeline cleanly at Day 0 (which then becomes 2585-06-31 or 2026-09-22):
The timeline begins at 00:00:00 (UTC+3:30) (Unix timestamp 1790022600). Genesis state, system bootstrapping, and initial node migrations execute cleanly within this 0-indexed day without producing negative offsets.
The official release of Mehr begins. User accounts created on launch day start from Day 1 (after 86,400s), ensuring all public identifiers follow clean positive natural numbers.
Implementation Examples
Self-contained production implementations in Go, JavaScript, TypeScript, Python, PHP, and Bash.
package muid
import (
"crypto/rand"
"fmt"
"math/big"
"regexp"
"strconv"
"strings"
"time"
)
const (
EpochTimestamp = 1790022600 // 2026-09-22 00:00:00 UTC+3:30
Base62Chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
)
var APITokenRegex = regexp.MustCompile(`^[0-9a-z]{6,12}:[0-9a-zA-Z]{43}$`)
func Generate() (raw int64, b36 string, err error) {
elapsed := time.Now().Unix() - EpochTimestamp
rBig, err := rand.Int(rand.Reader, big.NewInt(10000))
if err != nil {
return 0, "", err
}
raw = elapsed*10000 + rBig.Int64()
return raw, strconv.FormatInt(raw, 36), nil
}
func Parse(b36 string) (raw int64, createdAt time.Time, randomSuffix int, err error) {
raw, err = strconv.ParseInt(strings.ToLower(strings.TrimSpace(b36)), 36, 64)
if err != nil {
return 0, time.Time{}, 0, err
}
return raw, time.Unix(EpochTimestamp+(raw/10000), 0).UTC(), int(raw % 10000), nil
}
func GenerateSecret() (string, error) {
b := make([]byte, 32)
if _, err := rand.Read(b); err != nil {
return "", err
}
n := new(big.Int).SetBytes(b)
base := big.NewInt(62)
rem := new(big.Int)
var sb strings.Builder
for n.Sign() > 0 {
n.DivMod(n, base, rem)
sb.WriteByte(Base62Chars[rem.Int64()])
}
runes := []rune(sb.String())
for i, j := 0, len(runes)-1; i < j; i, j = i+1, j-1 {
runes[i], runes[j] = runes[j], runes[i]
}
res := string(runes)
for len(res) < 43 {
res = "0" + res
}
return res, nil
}
const EPOCH = 1790022600n; // 2026-09-22 00:00:00 UTC+3:30
const B62 = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
export const API_TOKEN_REGEX = /^[0-9a-z]{6,12}:[0-9a-zA-Z]{43}$/;
export function generateMuid() {
const elapsed = BigInt(Math.floor(Date.now() / 1000)) - EPOCH;
const rand = BigInt(crypto.getRandomValues(new Uint32Array(1))[0] % 10000);
const raw = elapsed * 10000n + rand;
return { raw, base36: raw.toString(36) };
}
export function parseMuid(b36) {
const clean = String(b36).trim().toLowerCase();
let raw = 0n;
for (const ch of clean) {
const code = ch.charCodeAt(0);
raw = raw * 36n + BigInt(code >= 48 && code <= 57 ? code - 48 : code - 87);
}
return { raw, base36: raw.toString(36), elapsed: raw / 10000n, rand: Number(raw % 10000n) };
}
export function generateSecret() {
const bytes = crypto.getRandomValues(new Uint8Array(32));
let num = 0n;
for (const b of bytes) num = (num << 8n) | BigInt(b);
let res = '';
while (num > 0n) {
res = B62[Number(num % 62n)] + res;
num /= 62n;
}
return res.padStart(43, '0');
}
export const EPOCH: bigint = 1790022600n;
export const API_TOKEN_REGEX = /^[0-9a-z]{6,12}:[0-9a-zA-Z]{43}$/;
const B62 = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
export function generateMuid(): { raw: bigint; base36: string } {
const elapsed = BigInt(Math.floor(Date.now() / 1000)) - EPOCH;
const rand = BigInt(crypto.getRandomValues(new Uint32Array(1))[0] % 10000);
const raw = elapsed * 10000n + rand;
return { raw, base36: raw.toString(36) };
}
export function parseMuid(b36: string): { raw: bigint; base36: string; elapsed: bigint; rand: number } {
const clean = b36.trim().toLowerCase();
let raw = 0n;
for (const ch of clean) {
const c = ch.charCodeAt(0);
raw = raw * 36n + BigInt(c >= 48 && c <= 57 ? c - 48 : c - 87);
}
return { raw, base36: raw.toString(36), elapsed: raw / 10000n, rand: Number(raw % 10000n) };
}
export function generateSecret(): string {
const bytes = crypto.getRandomValues(new Uint8Array(32));
let num = 0n;
for (const b of bytes) num = (num << 8n) | BigInt(b);
let res = '';
while (num > 0n) {
res = B62[Number(num % 62n)] + res;
num /= 62n;
}
return res.padStart(43, '0');
}
import re, secrets, time
EPOCH = 1790022600 # 2026-09-22 00:00:00 UTC+3:30
B36 = "0123456789abcdefghijklmnopqrstuvwxyz"
B62 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
API_TOKEN_REGEX = re.compile(r"^[0-9a-z]{6,12}:[0-9a-zA-Z]{43}$")
def encode_base36(n: int) -> str:
res = []
while n > 0:
n, r = divmod(n, 36)
res.append(B36[r])
return "".join(reversed(res)) or "0"
def generate_muid() -> tuple[int, str]:
elapsed = int(time.time()) - EPOCH
raw = elapsed * 10000 + secrets.randbelow(10000)
return raw, encode_base36(raw)
def parse_muid(b36: str) -> dict:
raw = int(b36.strip(), 36)
return {"raw": raw, "base36": encode_base36(raw), "elapsed": raw // 10000, "rand": raw % 10000}
def generate_secret() -> str:
n = int.from_bytes(secrets.token_bytes(32), "big")
res = []
while n > 0:
n, r = divmod(n, 62)
res.append(B62[r])
return "".join(reversed(res)).zfill(43)
<?php
const EPOCH = 1790022600;
const B62 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
const API_TOKEN_REGEX = '/^[0-9a-z]{6,12}:[0-9a-zA-Z]{43}$/';
function generateMuid(): array {
$raw = (time() - EPOCH) * 10000 + random_int(0, 9999);
return ['raw' => $raw, 'base36' => base_convert((string)$raw, 10, 36)];
}
function parseMuid(string $b36): array {
$raw = (int)base_convert(strtolower(trim($b36)), 36, 10);
return ['raw' => $raw, 'base36' => strtolower(trim($b36)), 'elapsed' => intdiv($raw, 10000), 'rand' => $raw % 10000];
}
function generateSecret(): string {
$bytes = array_values(unpack("C*", random_bytes(32)));
$res = "";
while (true) {
$zero = true; $rem = 0;
for ($i = 0; $i < 32; $i++) {
$cur = $rem * 256 + $bytes[$i];
$bytes[$i] = intdiv($cur, 62);
$rem = $cur % 62;
if ($bytes[$i] !== 0) $zero = false;
}
$res = B62[$rem] . $res;
if ($zero) break;
}
return str_pad($res, 43, '0', STR_PAD_LEFT);
}
#!/usr/bin/env bash
EPOCH=1790022600
B36="0123456789abcdefghijklmnopqrstuvwxyz"
B62="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
generate_muid() {
local raw=$(( ($(date +%s) - EPOCH) * 10000 + (RANDOM % 10000) ))
local n=$raw b36=""
while [ $n -gt 0 ]; do
b36="${B36:$((n % 36)):1}$b36"
n=$(( n / 36 ))
done
echo "$b36"
}
generate_secret() {
local bytes=( $(od -An -v -tu1 -N32 /dev/urandom) )
local res=""
while :; do
local zero=1 rem=0
for (( i=0; i<32; i++ )); do
local cur=$(( rem * 256 + bytes[i] ))
bytes[i]=$(( cur / 62 ))
rem=$(( cur % 62 ))
[ ${bytes[i]} -ne 0 ] && zero=0
done
res="${B62:$rem:1}$res"
[ $zero -eq 1 ] && break
done
while [ ${#res} -lt 43 ]; do res="0$res"; done
echo "$res"
}
echo "$(generate_muid):$(generate_secret)"