I'm working with firebase firestore and for some reason I need to hash every new user document ID to integer specifically a 16Bit UTF integer. Mostly it's an attempt at duplicating the .hashcode method in Dart.
what I have found and tried is this
// Convert to 32bit integer
const hashFunction = (string) => {
var hash = 0;
if (string.length == 0) return hash;
for (i = 0; i < string.length; i ) {
char = string.charCodeAt(i);
hash = (hash << 5) - hash char;
hash = hash & hash;
}
return hash >>> 0; // returns hash as positive integer
};
but this only converts to 32bit int. Any and all help is appreciated.
EDIT1: Using @selbie's changes i made some progress but the hash i'm getting is quite different from the .hashCode method in Dart and
is there anyway i can get thesame result
CodePudding user response:
If you only want a 16-bit hash, then:
Instead of this:
return hash >>> 0; // returns hash as positive integer
This:
return hash & 0xffff; // return lower 16-bits of hash value
This line:
if (string.length == 0) return hash;
Isn't needed since your for-loop will simply not run if string.length is 0.
Finally, not a good idea to have a variable name the same as a type. So let's just rename string
to be s
.
Here's a simplified solution:
const hashFunction = (s) => {
var hash = 0;
for (i = 0; i < s.length; i ) {
hash = (hash << 5) - hash s.charCodeAt(i);
hash = hash & hash; // prevent overflow from happening
}
return hash & 0xffff; // returns lower 16-bit of hash value
};
With that in mind, a 16-bit hash isn't a very strong hash. There are sure to be collisions after a few thousand strings are hashed. Consider a crytographically strong hash or a larger hash width as appropriate.
CodePudding user response:
function hashcode(string) {
let hash = 0;
for (let length = string.length, index = 0; index < length; index) {
hash = hash string.charCodeAt(index) & 0x1fffffff;
hash = hash ((hash & 0x7ffff) << 10) & 0x1fffffff;
hash ^= hash >> 6;
}
hash = hash ((hash & 0x3ffffff) << 3) & 0x1fffffff;
hash ^= hash >> 11;
return hash ((hash & 0x3fff) << 15) & 0x1fffffff;
}
from https://www.dartpad.dev/scripts/playground.dart.js line 6107
https://github.com/dart-lang/sdk/blob/main/sdk/lib/_internal/js_runtime/lib/js_string.dart#L448