Reputation: 145
I need to convert this php function into a coldfusion function for an api and I'm not having much luck. I'm not familiar enough with php or a coldfusion unpack equivalent and have just hit a brick wall.
function i32hash($str) {
$h = 0;
foreach (unpack('C*', $str) as &$p) { $h = (37 * $h + $p) % 4294967296; }
return ($h - 2147483648);
}
The end result should be i32hash('127.0.0.1:1935/vod/sample.mp4') = 565817233
this is the code I've been working with but its not working. I get an error back of "Cannot convert the value 4.294967296E9 to an integer because it cannot fit inside an integer." This happens at the modulus.
function i32hash(str) {
var h = 0;
// php unpack equivalent
str = toBinary(toBase64(str));
for(p in str) {
h = (37 * h + p) % 4294967296;
}
return h-2147483648;
}
Thanks for the help.
Updated answer, supplied by @Leigh in the comments below
function i32hash(str) {
var h = 0;
var strArray = charsetDecode(arguments.str, "us-ascii");
for(var p in strArray) {
h = precisionEvaluate((37 * h + p));
h = h.remainder( javacast("bigdecimal", 4294967296) );
}
return precisionEvaluate(h - 2147483648);
}
Upvotes: 1
Views: 213
Reputation: 28873
I am not a PHP guy, but my understanding is that unpack('C*',..)
should translate to decoding the string using ascii encoding, ie charsetDecode(theString, "us-ascii")
.
I get an error back of "Cannot convert the value 4.294967296E9 to an integer because it cannot fit inside an integer.
Unfortunately, CF's modulus operator, requires a 32 bit integer on the right side. The value 4294967296 exceeds the maximum allowed for integers. You will need to use a BigDecimal instead. The PrecisionEvaluate() function returns a BigDecimal. Use it on the first half of the expression:
firstPart = precisionEvaluate((37 * h + p));
Then obtain the modulus using the BigDecimal.remainder() method instead:
h = firstPart.remainder( javacast("bigdecimal", 4294967296) );
Finally, return the result:
precisionEvaluate(h - 2147483648)
Upvotes: 3