Blame view

node_modules/sha.js/hash.js 1.84 KB
aaac7fed   liuqimichale   add
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
  var Buffer = require('safe-buffer').Buffer
  
  // prototype class for hash functions
  function Hash (blockSize, finalSize) {
    this._block = Buffer.alloc(blockSize)
    this._finalSize = finalSize
    this._blockSize = blockSize
    this._len = 0
  }
  
  Hash.prototype.update = function (data, enc) {
    if (typeof data === 'string') {
      enc = enc || 'utf8'
      data = Buffer.from(data, enc)
    }
  
    var block = this._block
    var blockSize = this._blockSize
    var length = data.length
    var accum = this._len
  
    for (var offset = 0; offset < length;) {
      var assigned = accum % blockSize
      var remainder = Math.min(length - offset, blockSize - assigned)
  
      for (var i = 0; i < remainder; i++) {
        block[assigned + i] = data[offset + i]
      }
  
      accum += remainder
      offset += remainder
  
      if ((accum % blockSize) === 0) {
        this._update(block)
      }
    }
  
    this._len += length
    return this
  }
  
  Hash.prototype.digest = function (enc) {
    var rem = this._len % this._blockSize
  
    this._block[rem] = 0x80
  
    // zero (rem + 1) trailing bits, where (rem + 1) is the smallest
    // non-negative solution to the equation (length + 1 + (rem + 1)) === finalSize mod blockSize
    this._block.fill(0, rem + 1)
  
    if (rem >= this._finalSize) {
      this._update(this._block)
      this._block.fill(0)
    }
  
    var bits = this._len * 8
  
    // uint32
    if (bits <= 0xffffffff) {
      this._block.writeUInt32BE(bits, this._blockSize - 4)
  
    // uint64
    } else {
      var lowBits = (bits & 0xffffffff) >>> 0
      var highBits = (bits - lowBits) / 0x100000000
  
      this._block.writeUInt32BE(highBits, this._blockSize - 8)
      this._block.writeUInt32BE(lowBits, this._blockSize - 4)
    }
  
    this._update(this._block)
    var hash = this._hash()
  
    return enc ? hash.toString(enc) : hash
  }
  
  Hash.prototype._update = function () {
    throw new Error('_update must be implemented by subclass')
  }
  
  module.exports = Hash