Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F101804084
createHash.js
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Thu, Feb 13, 21:18
Size
3 KB
Mime Type
text/x-c++
Expires
Sat, Feb 15, 21:18 (2 d)
Engine
blob
Format
Raw Data
Handle
24232687
Attached To
rOACCT Open Access Compliance Check Tool (OACCT)
createHash.js
View Options
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
"use strict"
;
const
Hash
=
require
(
"./Hash"
);
const
BULK_SIZE
=
1000
;
const
digestCache
=
new
Map
();
class
BulkUpdateDecorator
extends
Hash
{
/**
* @param {Hash | function(): Hash} hashOrFactory function to create a hash
* @param {string=} hashKey key for caching
*/
constructor
(
hashOrFactory
,
hashKey
)
{
super
();
this
.
hashKey
=
hashKey
;
if
(
typeof
hashOrFactory
===
"function"
)
{
this
.
hashFactory
=
hashOrFactory
;
this
.
hash
=
undefined
;
}
else
{
this
.
hashFactory
=
undefined
;
this
.
hash
=
hashOrFactory
;
}
this
.
buffer
=
""
;
}
/**
* Update hash {@link https://nodejs.org/api/crypto.html#crypto_hash_update_data_inputencoding}
* @param {string|Buffer} data data
* @param {string=} inputEncoding data encoding
* @returns {this} updated hash
*/
update
(
data
,
inputEncoding
)
{
if
(
inputEncoding
!==
undefined
||
typeof
data
!==
"string"
||
data
.
length
>
BULK_SIZE
)
{
if
(
this
.
hash
===
undefined
)
this
.
hash
=
this
.
hashFactory
();
if
(
this
.
buffer
.
length
>
0
)
{
this
.
hash
.
update
(
this
.
buffer
);
this
.
buffer
=
""
;
}
this
.
hash
.
update
(
data
,
inputEncoding
);
}
else
{
this
.
buffer
+=
data
;
if
(
this
.
buffer
.
length
>
BULK_SIZE
)
{
if
(
this
.
hash
===
undefined
)
this
.
hash
=
this
.
hashFactory
();
this
.
hash
.
update
(
this
.
buffer
);
this
.
buffer
=
""
;
}
}
return
this
;
}
/**
* Calculates the digest {@link https://nodejs.org/api/crypto.html#crypto_hash_digest_encoding}
* @param {string=} encoding encoding of the return value
* @returns {string|Buffer} digest
*/
digest
(
encoding
)
{
let
cacheKey
;
if
(
this
.
hash
===
undefined
)
{
// short data for hash, we can use caching
cacheKey
=
`
$
{
this
.
hashKey
}
-
$
{
encoding
}
-
$
{
this
.
buffer
}
`
;
const
cacheEntry
=
digestCache
.
get
(
cacheKey
);
if
(
cacheEntry
!==
undefined
)
return
cacheEntry
;
this
.
hash
=
this
.
hashFactory
();
}
if
(
this
.
buffer
.
length
>
0
)
{
this
.
hash
.
update
(
this
.
buffer
);
}
const
digestResult
=
this
.
hash
.
digest
(
encoding
);
const
result
=
typeof
digestResult
===
"string"
?
digestResult
:
digestResult
.
toString
();
if
(
cacheKey
!==
undefined
)
{
digestCache
.
set
(
cacheKey
,
result
);
}
return
result
;
}
}
/* istanbul ignore next */
class
DebugHash
extends
Hash
{
constructor
()
{
super
();
this
.
string
=
""
;
}
/**
* Update hash {@link https://nodejs.org/api/crypto.html#crypto_hash_update_data_inputencoding}
* @param {string|Buffer} data data
* @param {string=} inputEncoding data encoding
* @returns {this} updated hash
*/
update
(
data
,
inputEncoding
)
{
if
(
typeof
data
!==
"string"
)
data
=
data
.
toString
(
"utf-8"
);
if
(
data
.
startsWith
(
"debug-digest-"
))
{
data
=
Buffer
.
from
(
data
.
slice
(
"debug-digest-"
.
length
),
"hex"
).
toString
();
}
this
.
string
+=
`
[
$
{
data
}](
$
{
new
Error
().
stack
.
split
(
"\n"
,
3
)[
2
]})
\
n
`
;
return
this
;
}
/**
* Calculates the digest {@link https://nodejs.org/api/crypto.html#crypto_hash_digest_encoding}
* @param {string=} encoding encoding of the return value
* @returns {string|Buffer} digest
*/
digest
(
encoding
)
{
return
"debug-digest-"
+
Buffer
.
from
(
this
.
string
).
toString
(
"hex"
);
}
}
let
crypto
=
undefined
;
/**
* Creates a hash by name or function
* @param {string | typeof Hash} algorithm the algorithm name or a constructor creating a hash
* @returns {Hash} the hash
*/
module
.
exports
=
algorithm
=>
{
if
(
typeof
algorithm
===
"function"
)
{
return
new
BulkUpdateDecorator
(()
=>
new
algorithm
());
}
switch
(
algorithm
)
{
// TODO add non-cryptographic algorithm here
case
"debug"
:
return
new
DebugHash
();
default
:
if
(
crypto
===
undefined
)
crypto
=
require
(
"crypto"
);
return
new
BulkUpdateDecorator
(
()
=>
crypto
.
createHash
(
algorithm
),
algorithm
);
}
};
Event Timeline
Log In to Comment