31 lines
1.1 KiB
TypeScript
31 lines
1.1 KiB
TypeScript
|
export function generateStealthId(length: number = 32): string {
|
|||
|
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
|||
|
const base = chars.length;
|
|||
|
|
|||
|
const randomChars = (count: number): string =>
|
|||
|
Array.from({ length: count }, () => chars.charAt(Math.floor(Math.random() * base))).join('');
|
|||
|
|
|||
|
// 生成前 length - 1 位
|
|||
|
const body = randomChars(length - 1);
|
|||
|
|
|||
|
// 将 body 每个字符的 charCode 累加,再 mod base,作为校验位
|
|||
|
const sum = body.split('').reduce((acc, c) => acc + c.charCodeAt(0), 0);
|
|||
|
const checksum = chars.charAt(sum % base);
|
|||
|
|
|||
|
return body + checksum;
|
|||
|
}
|
|||
|
|
|||
|
export function isStealthId(id: string): boolean {
|
|||
|
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
|||
|
const base = chars.length;
|
|||
|
|
|||
|
if (!/^[A-Za-z0-9]{32}$/.test(id)) return false;
|
|||
|
|
|||
|
const body = id.slice(0, -1);
|
|||
|
const expectedChecksum = id.slice(-1);
|
|||
|
|
|||
|
const sum = body.split('').reduce((acc, c) => acc + c.charCodeAt(0), 0);
|
|||
|
const checksum = chars.charAt(sum % base);
|
|||
|
|
|||
|
return checksum === expectedChecksum;
|
|||
|
}
|