@datadayrepos/js-id-web
Version:
Utils for generating identifiers in javascript browser environment. Using web crypto engine for random number generation.
75 lines (74 loc) • 3.12 kB
JavaScript
export async function computeSHA256String(input, n = 1) {
const maxLength = 32;
const lengthToTake = Math.min(n, maxLength);
const encoder = new TextEncoder();
const data = encoder.encode(input);
const hashBuffer = await window.crypto.subtle.digest('SHA-256', data);
const hashArray = Array.from(new Uint8Array(hashBuffer));
return hashArray.slice(0, lengthToTake);
}
async function computeHash(input, algorithm) {
if (typeof window === 'undefined' || !window.crypto || !window.crypto.subtle) {
return { error: 'Web Crypto API not supported in this environment.', result: null };
}
let dataBuffer;
if (input instanceof Blob || input instanceof File) {
try {
dataBuffer = await input.arrayBuffer();
}
catch (e) {
console.error('Error reading Blob/File as ArrayBuffer:', e);
return { error: `Failed to read file/blob: ${e instanceof Error ? e.message : String(e)}`, result: null };
}
}
else if (typeof input === 'string') {
const encoder = new TextEncoder();
dataBuffer = encoder.encode(input).buffer;
}
else if (input instanceof ArrayBuffer) {
dataBuffer = input;
}
else {
return { error: 'Unsupported input type. Must be string, ArrayBuffer, Blob, or File.', result: null };
}
try {
const hashBuffer = await window.crypto.subtle.digest(algorithm, dataBuffer);
return { error: null, result: new Uint8Array(hashBuffer) };
}
catch (e) {
console.error(`Error computing ${algorithm} hash:`, e);
return { error: `Failed to compute hash with ${algorithm}: ${e instanceof Error ? e.message : String(e)}`, result: null };
}
}
export async function computeSHA256(input, n = 1) {
const { error, result } = await computeHash(input, 'SHA-256');
if (error || !(result instanceof Uint8Array)) {
throw new Error(`Failed to compute SHA-256 hash: ${error || 'Unknown error'}`);
}
const maxLength = 32;
const lengthToTake = Math.min(n, maxLength);
const hashArray = Array.from(result);
return hashArray.slice(0, lengthToTake);
}
export async function computeSHA256Hex(input) {
const { error, result } = await computeHash(input, 'SHA-256');
if (error || !(result instanceof Uint8Array)) {
return { error: error || 'Failed to get hash buffer.', result: null };
}
const hexHash = Array.from(result).map(b => b.toString(16).padStart(2, '0')).join('');
return { error: null, result: hexHash };
}
export async function computeSHA512Hex(input) {
const { error, result } = await computeHash(input, 'SHA-512');
if (error || !(result instanceof Uint8Array)) {
return { error: error || 'Failed to get hash buffer.', result: null };
}
const hexHash = Array.from(result).map(b => b.toString(16).padStart(2, '0')).join('');
return { error: null, result: hexHash };
}
export async function hashFileSHA256(file) {
return computeSHA256Hex(file);
}
export async function hashFileSHA512(file) {
return computeSHA512Hex(file);
}