-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #147 from supercharge/base-hasher-refinements
Hasher refinements
- Loading branch information
Showing
10 changed files
with
285 additions
and
51 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
|
||
import type { BinaryLike, Encoding, Hash } from 'node:crypto' | ||
import { HashBuilderCallback } from './hash-builder.js' | ||
|
||
export interface BaseHasher { | ||
/** | ||
* Creates and returns a Node.js `Hash` instance for the given `algorithm` | ||
* and the related `input` with (optional) `inputEncoding`. When `input` | ||
* is a string and `inputEncoding` is omitted, it defaults to `utf8`. | ||
*/ | ||
createHash (algorithm: string, input: string | BinaryLike, inputEncoding?: Encoding): Hash | ||
|
||
/** | ||
* Returns an MD5 hash instance for the given `content`. | ||
*/ | ||
md5 (input: BinaryLike): string | ||
md5 (input: BinaryLike, hashBuilder: HashBuilderCallback): string | ||
md5 (input: string, inputEncoding: Encoding): Hash | ||
|
||
/** | ||
* Returns a SHA256 hash instance using SHA-2 for the given `content`. | ||
*/ | ||
sha256 (input: BinaryLike): string | ||
sha256 (input: BinaryLike, hashBuilder: HashBuilderCallback): string | ||
sha256 (input: string, inputEncoding: Encoding): Hash | ||
|
||
/** | ||
* Returns a SHA512 hash instance using SHA-2 for the given `content`. | ||
*/ | ||
sha512 (input: BinaryLike): string | ||
sha512 (input: BinaryLike, hashBuilder: HashBuilderCallback): string | ||
sha512 (input: string, inputEncoding: Encoding): Hash | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
|
||
import type { BinaryToTextEncoding, Encoding } from 'node:crypto' | ||
|
||
export type HashBuilderCallback = (hashBuilder: HashBuilder) => unknown | ||
|
||
export interface HashBuilderOptions { | ||
inputEncoding?: Encoding | ||
outputEncoding: BinaryToTextEncoding | ||
} | ||
|
||
export interface HashBuilder { | ||
inputEncoding(inputEncoding: Encoding): this | ||
toString(outputEncoding: BinaryToTextEncoding): void | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
|
||
import { HashBuilder as HashBuilderContract, HashBuilderOptions } from '@supercharge/contracts' | ||
import { BinaryToTextEncoding, Encoding } from 'crypto' | ||
|
||
export class HashBuilder implements HashBuilderContract { | ||
/** | ||
* Stores the hash builder options. | ||
*/ | ||
private readonly options: HashBuilderOptions | ||
|
||
constructor (options: HashBuilderOptions) { | ||
this.options = options | ||
} | ||
|
||
inputEncoding (inputEncoding: Encoding): this { | ||
this.options.inputEncoding = inputEncoding | ||
return this | ||
} | ||
|
||
digest (encoding: BinaryToTextEncoding): void { | ||
this.options.outputEncoding = encoding | ||
} | ||
|
||
toString (encoding: BinaryToTextEncoding): void { | ||
this.digest(encoding) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
|
||
import { test } from 'uvu' | ||
import { expect } from 'expect' | ||
import { BaseHasher } from '../dist/base-hasher.js' | ||
import { Hash } from 'crypto' | ||
|
||
test('createHash', async () => { | ||
const hasher = new BaseHasher() | ||
|
||
const hash = hasher.createHash('sha256', 'supercharge') | ||
expect(hash instanceof Hash).toBe(true) | ||
expect(hash.digest('base64').endsWith('=')).toBe(true) | ||
}) | ||
|
||
test('md5 with value', async () => { | ||
const hasher = new BaseHasher() | ||
|
||
const md5 = hasher.md5('supercharge') | ||
expect(typeof md5 === 'string').toBe(true) | ||
expect(md5.endsWith('=')).toBe(true) | ||
}) | ||
|
||
test('md5 with input encoding', async () => { | ||
const hasher = new BaseHasher() | ||
|
||
const md5 = hasher.md5('supercharge', 'utf8') | ||
expect(md5 instanceof Hash).toBe(true) | ||
}) | ||
|
||
test('md5 with hash builder callback', async () => { | ||
const hasher = new BaseHasher() | ||
|
||
const md5 = hasher.md5('supercharge', hash => hash.toString('hex')) | ||
expect(typeof md5 === 'string').toBe(true) | ||
}) | ||
|
||
test('sha256 with value', async () => { | ||
const hasher = new BaseHasher() | ||
|
||
const sha256 = hasher.sha256('supercharge') | ||
expect(typeof sha256 === 'string').toBe(true) | ||
expect(sha256.endsWith('=')).toBe(true) | ||
}) | ||
|
||
test('sha256 with input encoding', async () => { | ||
const hasher = new BaseHasher() | ||
|
||
const sha256 = hasher.sha256('supercharge', 'utf8') | ||
expect(sha256 instanceof Hash).toBe(true) | ||
}) | ||
|
||
test('sha256 with hash builder callback', async () => { | ||
const hasher = new BaseHasher() | ||
|
||
const sha256 = hasher.sha256('supercharge', hash => hash.toString('hex')) | ||
expect(typeof sha256 === 'string').toBe(true) | ||
}) | ||
|
||
test('sha512 with value', async () => { | ||
const hasher = new BaseHasher() | ||
|
||
const sha512 = hasher.sha512('supercharge') | ||
expect(typeof sha512 === 'string').toBe(true) | ||
expect(sha512.endsWith('=')).toBe(true) | ||
}) | ||
|
||
test('sha512 with input encoding', async () => { | ||
const hasher = new BaseHasher() | ||
|
||
const sha512 = hasher.sha512('supercharge', 'utf8') | ||
expect(sha512 instanceof Hash).toBe(true) | ||
}) | ||
|
||
test('sha512 with hash builder callback', async () => { | ||
const hasher = new BaseHasher() | ||
|
||
const sha512 = hasher.sha512('supercharge', hash => hash.toString('hex')) | ||
expect(typeof sha512 === 'string').toBe(true) | ||
}) | ||
|
||
test('hashes are different from each other', async () => { | ||
const hasher = new BaseHasher() | ||
const input = 'supercharge' | ||
|
||
expect(hasher.md5(input)).toEqual(hasher.md5(input)) | ||
expect(hasher.md5(input)).not.toEqual(hasher.sha256(input)) | ||
expect(hasher.md5(input)).not.toEqual(hasher.sha512(input)) | ||
|
||
expect(hasher.sha256(input)).toEqual(hasher.sha256(input)) | ||
expect(hasher.sha256(input)).not.toEqual(hasher.md5(input)) | ||
expect(hasher.sha256(input)).not.toEqual(hasher.sha512(input)) | ||
|
||
expect(hasher.sha512(input)).toEqual(hasher.sha512(input)) | ||
expect(hasher.sha512(input)).not.toEqual(hasher.md5(input)) | ||
expect(hasher.sha512(input)).not.toEqual(hasher.sha256(input)) | ||
}) | ||
|
||
test('hash builder', async () => { | ||
const hasher = new BaseHasher() | ||
|
||
const sha512 = hasher.sha512('supercharge', hash => { | ||
hash | ||
.inputEncoding('utf8') | ||
.toString('hex') | ||
}) | ||
|
||
expect(typeof sha512 === 'string').toBe(true) | ||
}) | ||
|
||
test.run() |
Oops, something went wrong.