import * as plugins from './plugins.js'; import { sha256Fallback } from './sha256.fallback.js'; /** * Convert ArrayBuffer to hex string */ const hex = (buffer: ArrayBuffer): string => { const hexCodes: string[] = []; const view = new DataView(buffer); for (let i = 0; i < view.byteLength; i += 4) { // Using getUint32 reduces the number of iterations needed (we process 4 bytes each time) const value = view.getUint32(i); // toString(16) will give the hex representation of the number without padding const stringValue = value.toString(16); // We use concatenation and slice for padding const padding = '00000000'; const paddedValue = (padding + stringValue).slice(-padding.length); hexCodes.push(paddedValue); } // Join all the hex strings into one return hexCodes.join(""); }; /** * Check if crypto.subtle is available */ const isCryptoSubtleAvailable = (): boolean => { return typeof crypto !== 'undefined' && crypto.subtle !== undefined; }; /** * Computes sha256 Hash from String */ export const sha256FromString = async (stringArg: string): Promise => { // Get the string as arraybuffer. const buffer = (new TextEncoder()).encode(stringArg); if (isCryptoSubtleAvailable()) { const hash = await crypto.subtle.digest("SHA-256", buffer); const result = hex(hash); return result; } else { // Use fallback for non-HTTPS environments return sha256Fallback(buffer); } }; /** * Computes sha256 Hash from String synchronously * Note: In browser environment, this is still async internally but we maintain the API */ export const sha256FromStringSync = (stringArg: string): string => { console.warn('sha256FromStringSync is not truly synchronous in browser environment'); throw new Error('sha256FromStringSync is not supported in browser environment. Use sha256FromString instead.'); }; /** * Computes sha256 Hash from ArrayBuffer */ export const sha256FromBuffer = async (bufferArg: ArrayBuffer | Uint8Array): Promise => { if (isCryptoSubtleAvailable()) { const hash = await crypto.subtle.digest("SHA-256", bufferArg); const result = hex(hash); return result; } else { // Use fallback for non-HTTPS environments const uint8Array = bufferArg instanceof Uint8Array ? bufferArg : new Uint8Array(bufferArg); return sha256Fallback(uint8Array); } }; /** * computes sha265 Hash from Object */ export const sha265FromObject = async (objectArg: any): Promise => { const stringifiedObject = plugins.smartjson.stringify(objectArg); const hashResult = await sha256FromString(stringifiedObject); return hashResult; }; /** * creates sha256 Hash from Stream * Note: Not supported in browser environment */ export const sha256FromStream = (input: any): Promise => { throw new Error('sha256FromStream is not supported in browser environment'); }; /** * creates sha256 Hash from File * Note: Not supported in browser environment */ export const sha256FromFile = async (filePath: string): Promise => { throw new Error('sha256FromFile is not supported in browser environment'); }; /** * Computes MD5 Hash from String * Note: MD5 is not natively supported by Web Crypto API */ export const md5FromString = async (stringToHash: string): Promise => { throw new Error('md5FromString is not supported in browser environment. Web Crypto API does not support MD5.'); };