Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
80556 views
1
//prototype class for hash functions
2
function Hash (blockSize, finalSize) {
3
this._block = new Buffer(blockSize) //new Uint32Array(blockSize/4)
4
this._finalSize = finalSize
5
this._blockSize = blockSize
6
this._len = 0
7
this._s = 0
8
}
9
10
Hash.prototype.update = function (data, enc) {
11
if ("string" === typeof data) {
12
enc = enc || "utf8"
13
data = new Buffer(data, enc)
14
}
15
16
var l = this._len += data.length
17
var s = this._s || 0
18
var f = 0
19
var buffer = this._block
20
21
while (s < l) {
22
var t = Math.min(data.length, f + this._blockSize - (s % this._blockSize))
23
var ch = (t - f)
24
25
for (var i = 0; i < ch; i++) {
26
buffer[(s % this._blockSize) + i] = data[i + f]
27
}
28
29
s += ch
30
f += ch
31
32
if ((s % this._blockSize) === 0) {
33
this._update(buffer)
34
}
35
}
36
this._s = s
37
38
return this
39
}
40
41
Hash.prototype.digest = function (enc) {
42
// Suppose the length of the message M, in bits, is l
43
var l = this._len * 8
44
45
// Append the bit 1 to the end of the message
46
this._block[this._len % this._blockSize] = 0x80
47
48
// and then k zero bits, where k is the smallest non-negative solution to the equation (l + 1 + k) === finalSize mod blockSize
49
this._block.fill(0, this._len % this._blockSize + 1)
50
51
if (l % (this._blockSize * 8) >= this._finalSize * 8) {
52
this._update(this._block)
53
this._block.fill(0)
54
}
55
56
// to this append the block which is equal to the number l written in binary
57
// TODO: handle case where l is > Math.pow(2, 29)
58
this._block.writeInt32BE(l, this._blockSize - 4)
59
60
var hash = this._update(this._block) || this._hash()
61
62
return enc ? hash.toString(enc) : hash
63
}
64
65
Hash.prototype._update = function () {
66
throw new Error('_update must be implemented by subclass')
67
}
68
69
module.exports = Hash
70
71