Dart - Calculate Hash Digest

This tutorial shows you how to generate digest in Dart with crypto library using MD5, SHA1, SHA224, SHA256, SHA384, and SHA512 algorithms.

Hash functions are usually used to protect sensitive data. It converts a value into another by using mathematical function. The output of a hash function is called digest. There are various algorithms for generating digest, MD5 and SHA algorithms are the most commonly used. If you are using Dart, the algorithms mentioned above are available in crypto package.

Each algorithm is implemented as a different class, with a method called convert for generating the digest. It takes an argument of type List<int>. So you have to convert the data to be hashed into a List<int>. It can be done by encoding the data first, for example using UTF-8 encoder which is available by importing dart:convert.

  var bytes = utf8.encode('woolha');

After that, you can generate the digest by calling convert method with the bytes as the argument. The below example is for SHA1. The return value is a Digest in hexadecimal digits.

If you need to get the result in bytes, you can use the bytes property.

  sha1Result.bytes
  Digest sha1Digest = sha1.convert(bytes);

Below are some examples using various algorithms.

   import 'package:crypto/crypto.dart';
  import 'package:convert/convert.dart';
  import 'dart:convert';
  
  void main() {
    var bytes = utf8.encode('woolhadotcom');
  
    Digest md5Result = md5.convert(bytes);
    Digest sha1Result = sha1.convert(bytes);
    Digest sha224Result = sha224.convert(bytes);
    Digest sha256Result = sha256.convert(bytes);
    Digest sha384Result = sha384.convert(bytes);
    Digest sha512Result = sha512.convert(bytes);
  
    print('MD5: $md5Result');
    print('SHA1: $sha1Result');
    print('SHA224: $sha224Result');
    print('SHA256: $sha256Result');
    print('SHA384: $sha384Result');
    print('SHA512: $sha512Result');
  
    print('SHA1 Digest bytes: ${sha1Result.bytes}');
  }
  

Output:

  MD5: 0c3218227f2fdf73f7cad02389701120
  SHA1: 2335937df6a8278fb070034a2d7ca7bf12158d1e
  SHA224: be240082aec0bb79d73a663691e0ef05b011659ce8fdad215a38cd41
  SHA256: 37066049a36a44256a8014f9caf443dd2d6075ab83668c064d0b950b36206fc9
  SHA384: 090fbd7a7da23a0791a769123bdc580a347d624ff3b16cf03deb7a0e3c073fec9c64b3816359f1d600b46d47afd67e2d
  SHA512: 5c75ca70804c3ca8b21809960930b79b2e55517140803e29f52cbe98107987f614a8990b35adde08a748f5ca4cdec1efd024352e561faf47de331ae84addda11
  SHA1 Digest bytes: [35, 53, 147, 125, 246, 168, 39, 143, 176, 112, 3, 74, 45, 124, 167, 191, 18, 21, 141, 30]

Generating Digest from Multiple Chunks.

What if the data or bytes are chunked. You can use startChunkedConversion method instead with a Sink<Digest> as the argument.

  var output = new AccumulatorSink();

  ByteConversionSink input = sha512.startChunkedConversion(output);

For each chunk of bytes, you need to add it to input using input.add(bytes);. After finished, use input.close(); to close the sink. To get the output in hexadecimal string, use output.events.single.

Below is the full code.

  import 'package:crypto/crypto.dart';
  import 'package:convert/convert.dart';
  import 'dart:convert';
  
  class Person {
    int id;
    String name;
  
    Person({this.id, this.name});
  }
  
  void main() {
    List<List<int>> bytesChunks = [
      utf8.encode('woolha'),
      utf8.encode('dot'),
      utf8.encode('com')
    ];
  
    var output = new AccumulatorSink<Digest>();
  
    ByteConversionSink input = sha512.startChunkedConversion(output);
    bytesChunks.forEach((List<int> bytes) { input.add(bytes); });
    input.close();
  
    Digest result = output.events.single;
  
    print('Result: $result');
  }
  

Here's the output of the above code.

  Result: 5c75ca70804c3ca8b21809960930b79b2e55517140803e29f52cbe98107987f614a8990b35adde08a748f5ca4cdec1efd024352e561faf47de331ae84addda11