I think we can use String.compareTo and MD5 to make simple one (hash collision will still exist).
Steps:
uses String.compareTo to check two input strings
if compreTo returns >0, then uses MD5 to get the hash value for "$s1${s1.length}$s2${s2.length}", otherwise, uses "$s2${s2.length}$s1${s1.length}". Please see first two test cases in the snippet to see why adding String.length into the calculation.
Snippet:
import 'dart:convert';
import 'package:crypto/crypto.dart';
String genHash(String s1, String s2) {
if (s1.compareTo(s2) > 0) return md5.convert(utf8.encode("$s1${s1.length}$s2${s2.length}")).toString();
else return md5.convert(utf8.encode("$s2${s2.length}$s1${s1.length}")).toString();
}
void main() {
String s1 = '11';
String s2 = '12';
print(genHash(s1, s2));
print(genHash(s2, s1));
assert(genHash(s1, s2) == genHash(s2, s1));
String s3 = '1';
String s4 = '121';
print(genHash(s3, s4));
print(genHash(s4, s3));
assert(genHash(s3, s4) == genHash(s4, s3) && genHash(s4, s3) != genHash(s2, s1));
s1 = '1234';
s2 = '123';
print(genHash(s1, s2));
print(genHash(s2, s1));
assert(genHash(s1, s2) == genHash(s2, s1));
s1 = '123';
s2 = '123';
print(genHash(s1, s2));
print(genHash(s2, s1));
assert(genHash(s1, s2) == genHash(s2, s1));
s1 = '1';
s2 = '2';
print(genHash(s1, s2));
print(genHash(s2, s1));
assert(genHash(s1, s2) == genHash(s2, s1));
s1 = '';
s2 = '';
print(genHash(s1, s2));
print(genHash(s2, s1));
assert(genHash(s1, s2) == genHash(s2, s1));
s1 = ' ';
s2 = '';
print(genHash(s1, s2));
print(genHash(s2, s1));
assert(genHash(s1, s2) == genHash(s2, s1));
}