renhack
renhack

Reputation: 145

PHP's unpack in Coldfusion

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

Answers (1)

Leigh
Leigh

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

Related Questions