Skip to content

Commit

Permalink
Require Node.js 12.20 and move to ESM
Browse files Browse the repository at this point in the history
  • Loading branch information
sindresorhus committed Aug 22, 2021
1 parent 03fe6a4 commit a764d9b
Show file tree
Hide file tree
Showing 8 changed files with 99 additions and 148 deletions.
6 changes: 2 additions & 4 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,10 @@ jobs:
fail-fast: false
matrix:
node-version:
- 14
- 12
- 10
- 16
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
- uses: actions/setup-node@v2
with:
node-version: ${{ matrix.node-version }}
- run: npm install
Expand Down
57 changes: 20 additions & 37 deletions index.d.ts
Original file line number Diff line number Diff line change
@@ -1,46 +1,29 @@
declare namespace fnv1a {
interface Options {
/**
The bit size of the hash.
@default 32
*/
size?: 32 | 64 | 128 | 256 | 512 | 1024;
}
}

declare const fnv1a: {
export interface Options {
/**
[FNV-1a](https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function) non-cryptographic hash function.
@returns The hash as a positive integer.
The bit size of the hash.
@example
```
import fnv1a = require('@sindresorhus/fnv1a');
fnv1a('πŸ¦„πŸŒˆ');
//=> 2868248295
```
@default 32
*/
(string: string): number;
readonly size?: 32 | 64 | 128 | 256 | 512 | 1024;
}

/**
[FNV-1a](https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function) non-cryptographic hash function.
/**
[FNV-1a](https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function) non-cryptographic hash function.
Generate a larger hash using `BigInt`.
@returns The hash as a positive `BigInt`.
@returns The hash as a positive BigInt.
@example
```
import fnv1a from '@sindresorhus/fnv1a';
@example
```
import fnv1a = require('@sindresorhus/fnv1a');
fnv1a('πŸ¦„πŸŒˆ', {size: 32});
//=> 2868248295n
fnv1a.bigInt('πŸ¦„πŸŒˆ', {size: 128});
//=> 13487074350300261116944693128525960095n
```
*/
bigInt(string: string, options?: fnv1a.Options): bigint;
};
fnv1a('πŸ¦„πŸŒˆ', {size: 128});
//=> 13487074350300261116944693128525960095n
export = fnv1a;
Number(fnv1a('πŸ¦„πŸŒˆ', {size: 32}));
//=> 2868248295
```
*/
export default function fnv1a(string: string, options?: Options): bigint;
60 changes: 16 additions & 44 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,50 +1,25 @@
'use strict';

// FNV_PRIMES and FNV_OFFSETS from
// http://www.isthe.com/chongo/tech/comp/fnv/index.html#FNV-param

const FNV_PRIMES = {
32: 16777619n,
64: 1099511628211n,
128: 309485009821345068724781371n,
256: 374144419156711147060143317175368453031918731002211n,
512: 35835915874844867368919076489095108449946327955754392558399825615420669938882575126094039892345713852759n,
1024: 5016456510113118655434598811035278955030765345404790744303017523831112055108147451509157692220295382716162651878526895249385292291816524375083746691371804094271873160484737966720260389217684476157468082573n
32: 16_777_619n,
64: 1_099_511_628_211n,
128: 309_485_009_821_345_068_724_781_371n,
256: 374_144_419_156_711_147_060_143_317_175_368_453_031_918_731_002_211n,
512: 35_835_915_874_844_867_368_919_076_489_095_108_449_946_327_955_754_392_558_399_825_615_420_669_938_882_575_126_094_039_892_345_713_852_759n,
1024: 5_016_456_510_113_118_655_434_598_811_035_278_955_030_765_345_404_790_744_303_017_523_831_112_055_108_147_451_509_157_692_220_295_382_716_162_651_878_526_895_249_385_292_291_816_524_375_083_746_691_371_804_094_271_873_160_484_737_966_720_260_389_217_684_476_157_468_082_573n,
};

const FNV_OFFSETS = {
32: 2166136261n,
64: 14695981039346656037n,
128: 144066263297769815596495629667062367629n,
256: 100029257958052580907070968620625704837092796014241193945225284501741471925557n,
512: 9659303129496669498009435400716310466090418745672637896108374329434462657994582932197716438449813051892206539805784495328239340083876191928701583869517785n,
1024: 14197795064947621068722070641403218320880622795441933960878474914617582723252296732303717722150864096521202355549365628174669108571814760471015076148029755969804077320157692458563003215304957150157403644460363550505412711285966361610267868082893823963790439336411086884584107735010676915n
32: 2_166_136_261n,
64: 14_695_981_039_346_656_037n,
128: 144_066_263_297_769_815_596_495_629_667_062_367_629n,
256: 100_029_257_958_052_580_907_070_968_620_625_704_837_092_796_014_241_193_945_225_284_501_741_471_925_557n,
512: 9_659_303_129_496_669_498_009_435_400_716_310_466_090_418_745_672_637_896_108_374_329_434_462_657_994_582_932_197_716_438_449_813_051_892_206_539_805_784_495_328_239_340_083_876_191_928_701_583_869_517_785n,
1024: 14_197_795_064_947_621_068_722_070_641_403_218_320_880_622_795_441_933_960_878_474_914_617_582_723_252_296_732_303_717_722_150_864_096_521_202_355_549_365_628_174_669_108_571_814_760_471_015_076_148_029_755_969_804_077_320_157_692_458_563_003_215_304_957_150_157_403_644_460_363_550_505_412_711_285_966_361_610_267_868_082_893_823_963_790_439_336_411_086_884_584_107_735_010_676_915n,
};

// Legacy implementation for 32-bit + number types
function fnv1a(string) {
// Handle Unicode code points > 0x7f
let hash = Number(FNV_OFFSETS[32]);
let isUnicoded = false;

for (let i = 0; i < string.length; i++) {
let characterCode = string.charCodeAt(i);

// Non-ASCII characters trigger the Unicode escape logic
if (characterCode > 0x7F && !isUnicoded) {
string = unescape(encodeURIComponent(string));
characterCode = string.charCodeAt(i);
isUnicoded = true;
}

hash ^= characterCode;
hash += (hash << 1) + (hash << 4) + (hash << 7) + (hash << 8) + (hash << 24);
}

return hash >>> 0;
}

function bigInt(string, {size = 32} = {}) {
export default function fnv1a(string, {size = 32} = {}) {
if (!FNV_PRIMES[size]) {
throw new Error('The `size` option must be one of 32, 64, 128, 256, 512, or 1024');
}
Expand All @@ -55,13 +30,13 @@ function bigInt(string, {size = 32} = {}) {
// Handle Unicode code points > 0x7f
let isUnicoded = false;

for (let i = 0; i < string.length; i++) {
let characterCode = string.charCodeAt(i);
for (let index = 0; index < string.length; index++) {
let characterCode = string.charCodeAt(index);

// Non-ASCII characters trigger the Unicode escape logic
if (characterCode > 0x7F && !isUnicoded) {
string = unescape(encodeURIComponent(string));
characterCode = string.charCodeAt(i);
characterCode = string.charCodeAt(index);
isUnicoded = true;
}

Expand All @@ -71,6 +46,3 @@ function bigInt(string, {size = 32} = {}) {

return hash;
}

module.exports = fnv1a;
module.exports.bigInt = bigInt;
6 changes: 3 additions & 3 deletions index.test-d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {expectType} from 'tsd';
import fnv1a = require('.');
import fnv1a from './index.js';

expectType<number>(fnv1a('πŸ¦„πŸŒˆ'));
expectType<bigint>(fnv1a.bigInt('πŸ¦„πŸŒˆ', {size: 128}));
expectType<bigint>(fnv1a('πŸ¦„πŸŒˆ'));
expectType<bigint>(fnv1a('πŸ¦„πŸŒˆ', {size: 128}));
2 changes: 1 addition & 1 deletion license
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com)

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

Expand Down
18 changes: 8 additions & 10 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,16 @@
"description": "FNV-1a non-cryptographic hash function",
"license": "MIT",
"repository": "sindresorhus/fnv1a",
"funding": "https://github.com/sponsors/sindresorhus",
"author": {
"name": "Sindre Sorhus",
"email": "sindresorhus@gmail.com",
"url": "sindresorhus.com"
"url": "https://sindresorhus.com"
},
"type": "module",
"exports": "./index.js",
"engines": {
"node": ">=10"
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
},
"scripts": {
"test": "xo && ava && tsd"
Expand Down Expand Up @@ -38,13 +41,8 @@
"bigint"
],
"devDependencies": {
"ava": "2.4.0",
"tsd": "0.11.0",
"xo": "0.25.3"
},
"xo": {
"globals": [
"BigInt"
]
"ava": "3.15.0",
"tsd": "0.17.0",
"xo": "0.44.0"
}
}
24 changes: 12 additions & 12 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,35 +15,35 @@ $ npm install @sindresorhus/fnv1a
## Usage

```js
const fnv1a = require('@sindresorhus/fnv1a');
import fnv1a from '@sindresorhus/fnv1a';

fnv1a('πŸ¦„πŸŒˆ');
//=> 2868248295
fnv1a('πŸ¦„πŸŒˆ', {size: 32});
//=> 2868248295n

fnv1a.bigInt('πŸ¦„πŸŒˆ', {size: 128});
fnv1a('πŸ¦„πŸŒˆ', {size: 128});
//=> 13487074350300261116944693128525960095n

Number(fnv1a('πŸ¦„πŸŒˆ', {size: 32}));
//=> 2868248295
```

## API

### fnv1a(string)

Returns the hash as a 32-bit positive integer.

### fnv1a.bigInt(string, options?)

Generate a larger hash using `BigInt`.
### fnv1a(string, options?)

Returns the hash as a positive `BigInt`.

If you need it as a `number`, use `32` as `size` and wrap the return value in `Number(…)`.

#### options

Type: `object`

##### size

Type: `number`\
Values: `32 | 64 | 128 | 256 | 512 | 1024`
Values: `32 | 64 | 128 | 256 | 512 | 1024`\
Default: `32`

The bit size of the hash.

Expand Down
Loading

0 comments on commit a764d9b

Please sign in to comment.