Compute MD5, SHA-1, SHA-256, and SHA-512 in browser-compatible AI runtimes using Web Crypto plus a local MD5 implementation.
Import directly into Dify, Coze, Cursor, or any tool-calling agent runtime.
{
"name": "calculate_hashes",
"description": "Calculate common hash values for text or binary content.",
"parameters": {
"type": "object",
"properties": {
"input_text": {
"type": "string",
"description": "Plain text to hash. Use either input_text or input_base64."
},
"input_base64": {
"type": "string",
"description": "Optional raw file content encoded as base64."
},
"algorithms": {
"type": "array",
"items": {
"type": "string",
"enum": ["md5", "sha1", "sha256", "sha512"]
},
"description": "Hash algorithms to compute. Defaults to all four."
}
}
}
}Paste this into your system prompt to keep the generated tool implementation aligned with the contract.
# Task Constraints: Hash Calculator Module
When implementing hashing in an AI runtime, you MUST preserve byte-level determinism.
## Core Prohibitions
- NEVER hash JavaScript strings with ad hoc Unicode conversions.
- NEVER claim MD5 is secure for password storage or signatures.
- NEVER silently alter line endings, trim whitespace, or normalize the input unless the caller explicitly asks for it.
## Standard Implementation
1. Convert input_text with TextEncoder() or decode input_base64 into raw bytes.
2. Use the exact same byte array for every algorithm.
3. Compute SHA-1, SHA-256, and SHA-512 with crypto.subtle.digest().
4. Use a dedicated MD5 implementation because Web Crypto does not provide MD5.
5. Return lowercase hexadecimal strings.
## Response Requirements
- If both input_text and input_base64 are missing, return a validation error.
- If algorithms is omitted, calculate all supported algorithms.
- Make it explicit that MD5 and SHA-1 are for compatibility checks, not modern security design.This implementation assumes an external md5Bytes(bytes) helper is available. SHA algorithms should come from Web Crypto so the same byte buffer is hashed consistently.
async function main(args) {
const requested = args.algorithms?.length
? args.algorithms
: ["md5", "sha1", "sha256", "sha512"];
if (!args.input_text && !args.input_base64) {
return { success: false, result: null, error: "Provide input_text or input_base64" };
}
try {
const bytes = args.input_base64
? Uint8Array.from(atob(args.input_base64), (char) => char.charCodeAt(0))
: new TextEncoder().encode(args.input_text);
const result = {};
if (requested.includes("md5")) {
result.md5 = md5Bytes(bytes);
}
const digestMap = {
sha1: "SHA-1",
sha256: "SHA-256",
sha512: "SHA-512",
};
for (const [key, algorithm] of Object.entries(digestMap)) {
if (!requested.includes(key)) continue;
const buffer = await crypto.subtle.digest(algorithm, bytes);
result[key] = Array.from(new Uint8Array(buffer))
.map((byte) => byte.toString(16).padStart(2, "0"))
.join("");
}
return { success: true, result };
} catch (error) {
return {
success: false,
result: null,
error: "Hashing failed: " + (error instanceof Error ? error.message : String(error)),
};
}
}