getHash method

Future<String> getHash(
  1. HashFunction hashFunction
)

Calculates the sticker pack's hash as specified by XEP-0449.

Implementation

Future<String> getHash(HashFunction hashFunction) async {
  // Build the meta string
  final metaTmp = [
    <int>[
      ...utf8.encode('name'),
      0x1f,
      0x1f,
      ...utf8.encode(name),
      0x1f,
      0x1e,
    ],
    <int>[
      ...utf8.encode('summary'),
      0x1f,
      0x1f,
      ...utf8.encode(summary),
      0x1f,
      0x1e,
    ],
  ]..sort(ioctetSortComparatorRaw);
  final metaString = List<int>.empty(growable: true);
  for (final m in metaTmp) {
    metaString.addAll(m);
  }
  metaString.add(0x1c);

  // Build item hashes
  final items = List<List<int>>.empty(growable: true);
  for (final sticker in stickers) {
    final tmp = List<int>.empty(growable: true)
      ..addAll(utf8.encode(sticker.metadata.desc!))
      ..add(0x1e);

    final hashes = List<List<int>>.empty(growable: true);
    for (final hash in sticker.metadata.hashes.keys) {
      hashes.add([
        ...utf8.encode(hash.toName()),
        0x1f,
        ...utf8.encode(sticker.metadata.hashes[hash]!),
        0x1f,
        0x1e,
      ]);
    }
    hashes.sort(ioctetSortComparatorRaw);

    for (final hash in hashes) {
      tmp.addAll(hash);
    }
    tmp.add(0x1d);
    items.add(tmp);
  }
  items.sort(ioctetSortComparatorRaw);
  final stickersString = List<int>.empty(growable: true);
  for (final item in items) {
    stickersString.addAll(item);
  }
  stickersString.add(0x1c);

  // Calculate the hash
  final rawHash = await CryptographicHashManager.hashFromData(
    hashFunction,
    [
      ...metaString,
      ...stickersString,
    ],
  );
  return base64.encode(rawHash).substring(0, 24);
}