Replace right shift with truncating divide (#128)

Closes #125

In JavaScript the shift operators cause numbers to be truncated to 32
bits, so the `>> 32` operation will always result in 0 on the web. This
causes a problem once the length of the file hits 512MB.
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f3b63c8..d6ec9e4 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,7 @@
 ## 3.0.2-dev
 
-- Require Dart 2.14.0.
+* Require Dart 2.14.0.
+* Fix bug calculating hashes for content larger than 512MB when compiled to JS.
 
 ## 3.0.1
 
diff --git a/lib/src/hash_sink.dart b/lib/src/hash_sink.dart
index adebf22..cd23823 100644
--- a/lib/src/hash_sink.dart
+++ b/lib/src/hash_sink.dart
@@ -161,7 +161,7 @@
     // We're essentially doing byteData.setUint64(offset, lengthInBits, _endian)
     // here, but that method isn't supported on dart2js so we implement it
     // manually instead.
-    var highBits = lengthInBits >> 32;
+    var highBits = lengthInBits ~/ 0x100000000; // >> 32
     var lowBits = lengthInBits & mask32;
     if (_endian == Endian.big) {
       byteData.setUint32(offset, highBits, _endian);
diff --git a/pubspec.yaml b/pubspec.yaml
index 7d413b7..44c3207 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -10,5 +10,6 @@
   typed_data: ^1.3.0
 
 dev_dependencies:
+  convert: ^3.0.0
   lints: ^1.0.0
   test: ^1.16.0
diff --git a/test/sha1_test.dart b/test/sha1_test.dart
index 9c1749e..4630d04 100644
--- a/test/sha1_test.dart
+++ b/test/sha1_test.dart
@@ -5,6 +5,7 @@
 import 'dart:async';
 import 'dart:convert';
 
+import 'package:convert/convert.dart';
 import 'package:crypto/crypto.dart';
 import 'package:test/test.dart';
 
@@ -44,6 +45,19 @@
       });
     }
   });
+  group('large file', () {
+    final chunk = List.filled(1024, 0);
+    test('produces correct hash', () async {
+      final sink = AccumulatorSink<Digest>();
+      final hash = sha1.startChunkedConversion(sink);
+      for (var i = 0; i < 512 * 1024; i++) {
+        hash.add(chunk);
+      }
+      hash.close();
+      expect(sink.events.single.toString(),
+          '5b088492c9f4778f409b7ae61477dec124c99033');
+    });
+  });
 }
 
 // Standard test vectors from: