Reputation: 38
So I have this hashing algorithm in JS, and I was wondering how I could reverse a hash it made? I know people ask these questions a lot, but this hashing algorithm is unique (I think). Here it is:
const stringToHash = 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;
}
Here's an example output it gave me: -566853151
Upvotes: 0
Views: 966
Reputation: 9411
If your message is solely upper case or solely lower case, the characters only differ within a block of 32, which is 2^5. Therefore when you shift the number by 5 bit positions, the next incoming character does not overlap.
Therefore you can start at the highest order bits, and read the first character, then think about how that character will have evolved through the various steps (shifting and subtracting). This will allow you to "undo" the effect of the first character.
You now have the first character removed and the remaining hash is simpler, being the hash of the remaining characters of the message. You can then repeat until all the characters are done.
If the message is longer, and especially if it is allowed to include a wider array of symbols, your task is much harder.
Let me know if this helps you get started:
const stringToHash = 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;
}
console.log(stringToHash("A").toString(2))
console.log(stringToHash("AA").toString(2))
console.log(stringToHash("AAA").toString(2))
console.log(stringToHash("B").toString(2))
console.log(stringToHash("BA").toString(2))
console.log(stringToHash("BAA").toString(2))
Upvotes: 1