Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions src/utils/hash.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,30 @@
* Works in both browser and Node.js environments using Web Crypto API.
*/

/**
* Simple FNV-1a 32-bit hash fallback for environments where
* crypto.subtle is unavailable (e.g. non-secure HTTP origins).
* Returns a hex string like SHA-256 but shorter (8 chars).
*/
function fnv1aHex(input: string): string {
let hash = 0x811c9dc5
for (let i = 0; i < input.length; i++) {
hash ^= input.charCodeAt(i)
hash = (hash * 0x01000193) >>> 0
}
return hash.toString(16).padStart(8, '0')
}

/**
* Compute SHA-256 hash of a string, returning hex-encoded result.
* In browser contexts where crypto.subtle is unavailable (e.g. non-secure
* HTTP origins), falls back to a simple FNV-1a hash so the page doesn't crash.
* Server-side callers always have crypto.subtle available (Node.js 18+).
*/
export async function sha256Hex(input: string): Promise<string> {
if (typeof window !== 'undefined' && !crypto?.subtle) {
return fnv1aHex(input)
}
const encoder = new TextEncoder()
const data = encoder.encode(input)
const hashBuffer = await crypto.subtle.digest('SHA-256', data)
Expand Down
Loading