2025-06-19 22:44:47 +00:00
|
|
|
import * as plugins from './plugins.js';
|
2025-06-19 23:03:36 +00:00
|
|
|
import { sha256Fallback } from './sha256.fallback.js';
|
2025-06-19 22:44:47 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* 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("");
|
|
|
|
};
|
|
|
|
|
2025-06-19 23:03:36 +00:00
|
|
|
/**
|
|
|
|
* Check if crypto.subtle is available
|
|
|
|
*/
|
|
|
|
const isCryptoSubtleAvailable = (): boolean => {
|
|
|
|
return typeof crypto !== 'undefined' && crypto.subtle !== undefined;
|
|
|
|
};
|
|
|
|
|
2025-06-19 22:44:47 +00:00
|
|
|
/**
|
|
|
|
* Computes sha256 Hash from String
|
|
|
|
*/
|
|
|
|
export const sha256FromString = async (stringArg: string): Promise<string> => {
|
|
|
|
// Get the string as arraybuffer.
|
|
|
|
const buffer = (new TextEncoder()).encode(stringArg);
|
2025-06-19 23:03:36 +00:00
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
2025-06-19 22:44:47 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 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<string> => {
|
2025-06-19 23:03:36 +00:00
|
|
|
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);
|
|
|
|
}
|
2025-06-19 22:44:47 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* computes sha265 Hash from Object
|
|
|
|
*/
|
|
|
|
export const sha265FromObject = async (objectArg: any): Promise<string> => {
|
|
|
|
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<string> => {
|
|
|
|
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<string> => {
|
|
|
|
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<string> => {
|
|
|
|
throw new Error('md5FromString is not supported in browser environment. Web Crypto API does not support MD5.');
|
|
|
|
};
|