Skip to content

Commit fd53c14

Browse files
committed
Implement node:crypto one-shot hash()
1 parent d3fa366 commit fd53c14

File tree

3 files changed

+61
-0
lines changed

3 files changed

+61
-0
lines changed

src/node/crypto.ts

+3
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ import {
4545
Hash,
4646
HashOptions,
4747
Hmac,
48+
hash,
4849
} from 'node-internal:crypto_hash';
4950

5051
import {
@@ -119,6 +120,7 @@ export {
119120
Hash,
120121
HashOptions,
121122
Hmac,
123+
hash,
122124
// Hkdf
123125
hkdf,
124126
hkdfSync,
@@ -250,6 +252,7 @@ export default {
250252
createHash,
251253
createHmac,
252254
getHashes,
255+
hash,
253256
// Hkdf
254257
hkdf,
255258
hkdfSync,

src/node/internal/crypto_hash.ts

+25
Original file line numberDiff line numberDiff line change
@@ -300,4 +300,29 @@ Hmac.prototype._flush = Hash.prototype._flush;
300300
// eslint-disable-next-line @typescript-eslint/unbound-method
301301
Hmac.prototype._transform = Hash.prototype._transform;
302302

303+
export function hash(
304+
algorithm: string,
305+
data: string | ArrayBufferView,
306+
outputEncoding: string = 'hex'
307+
) {
308+
validateString(algorithm, 'algorithm');
309+
validateString(outputEncoding, 'outputEncoding');
310+
311+
if (typeof data === 'string') {
312+
const hash = createHash(algorithm);
313+
hash.update(data, 'utf8');
314+
return hash.digest(outputEncoding);
315+
} else if (isArrayBufferView(data)) {
316+
const hash = createHash(algorithm);
317+
hash.update(data, 'utf8');
318+
return hash.digest(outputEncoding);
319+
}
320+
321+
throw new ERR_INVALID_ARG_TYPE(
322+
'data',
323+
['string', 'Buffer', 'TypedArray', 'DataView'],
324+
data
325+
);
326+
}
327+
303328
export { Hash, Hmac };

src/workerd/api/node/tests/crypto_hash-test.js

+33
Original file line numberDiff line numberDiff line change
@@ -291,3 +291,36 @@ export const hash_pipe_test = {
291291
await p.promise;
292292
},
293293
};
294+
295+
export const hash_one_shot = {
296+
test() {
297+
const string = 'Node.js';
298+
assert.strictEqual(
299+
crypto.hash('sha1', 'Node.js'),
300+
'10b3493287f831e81a438811a1ffba01f8cec4b7'
301+
);
302+
303+
const check = Buffer.from(
304+
'10b3493287f831e81a438811a1ffba01f8cec4b7',
305+
'hex'
306+
);
307+
const base64 = 'Tm9kZS5qcw==';
308+
assert.deepStrictEqual(
309+
crypto.hash('sha1', Buffer.from(base64, 'base64'), 'buffer'),
310+
check
311+
);
312+
313+
assert.throws(() => crypto.hash(1), {
314+
code: 'ERR_INVALID_ARG_TYPE',
315+
});
316+
assert.throws(() => crypto.hash('sha1', 12), {
317+
code: 'ERR_INVALID_ARG_TYPE',
318+
});
319+
assert.throws(() => crypto.hash('sha1', 'test', 123), {
320+
code: 'ERR_INVALID_ARG_TYPE',
321+
});
322+
assert.throws(() => crypto.hash('unknown', 'what'), {
323+
message: /Digest method not supported/,
324+
});
325+
},
326+
};

0 commit comments

Comments
 (0)