TL/DR: What logic can I add to SELECT (-1816598198 << 8);
to ensure that it returns -1192670720
like in JS/TS?
Full Question:
I’m having trouble porting a JS/TS function to MySQL. The function I have is:
const BuildIDLookupTable = [0x00000000, 0x04c11db7, 0x09823b6e, /* ... */ 0xb8757bda, 0xb5365d03, 0xb1f740b4];
function getBuildId(gPsyonixBuildId: string): number {
let result = -1;
for (const character of gPsyonixBuildId) {
const charCode = character.charCodeAt(0);
result = BuildIDLookupTable[(result >>> 24) ^ (charCode & 0xff)] ^ (result << 8);
result = BuildIDLookupTable[(result >>> 24) ^ (charCode >>> 8)] ^ (result << 8);
}
return ~result;
}
I created a MySQL table, build_id_lookup
, and inserted the proper values. I’ve got the MySQL function:
CREATE DEFINER=`stev`@`%` FUNCTION `getBuildId`(gPsyonixBuildId VARCHAR(256)) RETURNS bigint
DETERMINISTIC
BEGIN
DECLARE characterCode INT;
DECLARE characterIndex INT DEFAULT 0;
DECLARE gPsyonixBuildIdLength INT DEFAULT CHAR_LENGTH(gPsyonixBuildId);
DECLARE result BIGINT DEFAULT -1;
WHILE characterIndex < gPsyonixBuildIdLength DO
SET characterCode = ASCII(SUBSTRING(gPsyonixBuildId, characterIndex, 1));
SELECT CAST(`value` ^ (result << 8) AS SIGNED) INTO result FROM `build_id_lookup` WHERE `index` = result >> 24 & 0xff ^ (characterCode & 0xff);
-- The (result << 8) yields unexpected results in comparison to JS/TS.
SELECT CAST(`value` ^ (result << 8) AS SIGNED) INTO result FROM `build_id_lookup` WHERE `index` = result >> 24 & 0xff ^ (characterCode >> 8 & 0xff);
SET characterIndex = characterIndex + 1;
END WHILE;
RETURN ~result;
END
I’m finding that MySQL’s (result << 0x8)
is giving different results than JS/TS.
For example, SELECT (-1816598198 << 8);
yields 18446743608660412928
in MySQL, but yields -1192670720
in JS/TS.
Thanks!
2
Answers
I ended up creating a basic MySQL function to simulate overflow:
Which was just a port of my JS/TS function for doing the same:
fiddle