12

I am trying to convert a JavaScript hashing function to C# hashing to do the exact same thing. I'm 99% there but I hit a snag with decimals used in this custom function.
Am not sure why but this function convert a hashed value to a decimal for some odd reason and my problem is that decimals generated are not always the same length. The decimals in C# are quite a bit longer but are uniform length. The problem i am having is because rounding in C# works differently than JavaScript I don't know exactly at what decimal to round to create the equivalent length string.

Here is an example of two generated decimal strings that are appended to each other. Both start from 4,4 and 3 character strings:

4 char string generates 79957.88183577501
4 char string generates 160933.02806113224
3 char string generates 609.9111294990053

Using the exact same code C# generates using the exact same inputs:

79957.88183577500452161331162
160933.02806113221197323204919
609.91112949900524507144149035

If all strings were the same length it would not be a problem but I have no idea how to determine when JS will generate the longer decimal. Any clues? Comments? Opinions?

Unfortunately the receiving code is still the original JS which simply reverses the process hence I have to duplicate the end result perfectly for all inputs.

EDIT:

Here is the problematic section. Don't ask me why it works like that, I didn't write it.

// oString is a full string to be encoded
// oKey is a key to be used for encoding
function completeHash(oString,oKey) {
    if( oKey.length < 5 ) {
        window.alert( 'The key must be at least 5 characters long' );
        return oString;
    }
    var oKeyNum = new Array(), oOutStr = '', oOp = new Array('+=','/=','-=','*= 0.01 *');
    for (var x = 0; x < oKey.length; x++) {
        oKeyNum[x] = parseInt('0x' + completeEscape(oKey.charAt(x)));
    }

    for( var x = 0, y = ''; x < oString.length; x += Math.round( oKey.length / 2 ), y = 'O.O' ) {
        var theNum = parseInt( '0x' + completeEscape( oString.substr( x, Math.round( oKey.length / 2 ) ) ) );

        // next two lines are problematic with decimals not having equal length
        for( var z = 0; z < oKey.length; z++ ) {
            eval( 'theNum ' + oOp[z % 4] + ' ' + oKeyNum[z] + ';' );
            alert('theNum:' + theNum);
        }

        oOutStr += y + theNum;
    }
    return oOutStr;
}

completeEscape() function simply returns ASCII int codes for each character.

I got the whole thing working nicely except the length of the decimals.

Shadow The GPT Wizard
  • 66,030
  • 26
  • 140
  • 208
IcantSpell
  • 206
  • 3
  • 9
  • 6
    Why exactly is your hash a decimal in the first place? If you need precise round tripping of values, don't use a data type that inherently implies lossy conversions. – millimoose Oct 23 '12 at 22:20
  • 2
    So the "hash" is really an encoded string? Hashs are typically one-way computations. – Tejs Oct 23 '12 at 22:22
  • Could you show the javascript code and the C# implemenation of it? – Magnus Oct 23 '12 at 22:24
  • 1
    can't really show the code or i'd get fired probably :) – IcantSpell Oct 23 '12 at 22:26
  • Perhaps a part of it that demonstrates the problem. – Magnus Oct 23 '12 at 22:27
  • as for why the hash is getting decim...aled? i have no clu, this code was written way before me and is now a problem so it has to be converted to sever side. let me see what i can safely post. – IcantSpell Oct 23 '12 at 22:28
  • 1
    By the way, when you say `Decimal` do you mean floating-point value? To my knowledge there is no `Decimal` data type in javascript. – Magnus Oct 23 '12 at 22:40
  • yes floating point. i call it decimal in my head since i mostly do C# – IcantSpell Oct 23 '12 at 22:49

2 Answers2

5

If you're using Number in javascript, then use double in C#. Both are 64-bit IEEE 754 numbers (double-precision). You get the same values (updated after verifying this).

Peter Ivan
  • 1,467
  • 2
  • 14
  • 27
2

I think your problem relates to the javascript limit on double precision decimal numbers. This gives you about 16 digits worth of precision. You will need to consider using a work around based on strings. Additional details, including the work around can be found here How can I handle numbers bigger than 17-digits in Firefox/IE7?

Community
  • 1
  • 1
alistair
  • 1,054
  • 9
  • 10
  • that's what i thought at one point but then occasionally see a 17 digit number as in example #2 in the OP. – IcantSpell Oct 24 '12 at 18:19
  • doing bit more research i didn't exactly find a solution but i did develop other ideas on handling the problem without using this code so i can't post an answer to this one. Maybe one day i'll find an answer. Thanks all! – IcantSpell Oct 24 '12 at 21:44