finish method

Uint8List finish()

Pads, compresses the final block(s), and returns the digest. The hash cannot be updated afterwards; snapshot with copy first to continue a running stream.

Implementation

Uint8List finish() {
  if (_finished) {
    throw StateError('finish() called twice');
  }
  _finished = true;
  final bytes = _totalBytes;
  _buffer[_bufferLength++] = 0x80;
  if (_bufferLength > blockSize - 8) {
    _buffer.fillRange(_bufferLength, blockSize, 0);
    compress(_buffer, 0);
    _bufferLength = 0;
  }
  _buffer.fillRange(_bufferLength, blockSize - 8, 0);
  // 64-bit big-endian bit count, kept within web-safe arithmetic: the
  // high word via division, the low word from the 29 low bits only,
  // no shift ever sees a value ≥ 2^32 (a dart2js gotcha).
  final high = bytes ~/ 0x20000000;
  final low = (bytes & 0x1FFFFFFF) << 3;
  _buffer[blockSize - 8] = (high >>> 24) & 0xFF;
  _buffer[blockSize - 7] = (high >>> 16) & 0xFF;
  _buffer[blockSize - 6] = (high >>> 8) & 0xFF;
  _buffer[blockSize - 5] = high & 0xFF;
  _buffer[blockSize - 4] = low >>> 24;
  _buffer[blockSize - 3] = (low >>> 16) & 0xFF;
  _buffer[blockSize - 2] = (low >>> 8) & 0xFF;
  _buffer[blockSize - 1] = low & 0xFF;
  compress(_buffer, 0);
  final out = Uint8List(digestSize);
  writeDigest(out);
  return out;
}