dart-lang / core

This repository is home to core Dart packages.
https://pub.dev/publishers/dart.dev
BSD 3-Clause "New" or "Revised" License
19 stars 7 forks source link

MapEqualty Hash collides easily #668

Open SShayashi opened 11 months ago

SShayashi commented 11 months ago

From the MapEquality documentation, I thought that the combination of key and value must be the same to have a collision, but the value can be swapped and the hash value will still be the same. For example, the following maps have the same hash value.

import 'package:collection/collection.dart';

void main() {
  final map01 = {
    'key1': 1,
    'key2': 0,
    'key3': 'a',
  };
  final map02 = {
    'key1': 'a',
    'key2': 1,
    'key3': 0,
  };
  final hash01 = DeepCollectionEquality().hash(map01);
  final hash02 = DeepCollectionEquality().hash(map02);
  print(hash01 == hash02); // true.
}

Is this expected behavior?

dart info ``` $ dart info If providing this information as part of reporting a bug, please review the information below to ensure it only contains things you're comfortable posting publicly. #### General info - Dart 3.2.0 (stable) (Tue Nov 14 18:26:59 2023 +0000) on "macos_arm64" - on macos / Version 13.4 (Build 22F66) - locale is ja-JP #### Process info | Memory | CPU | Elapsed time | Command line | | -----: | ---: | -----------: | ------------------------------------------------------------------------------------------ | | 426 MB | 0.0% | 01-20:23:25 | dart language-server --client-id=Android-Studio --client-version=AI-222.4459.24 --protocol=analyzer | | 51 MB | 0.0% | 01-20:23:25 | flutter_tools.snapshot daemon ```
lrhn commented 11 months ago

It could probably be improved. It's an unordered hash, so the hashed of the entries are just xor'ed, but it probably should be an unordered hash of better hashed entries.