Solved

Translate 1 C (or PERL or PHP) script to ASP

Posted on 2003-11-15
22
350 Views
Last Modified: 2007-12-19
Hello ASP experts, can somebody translate this C (or PERL or PHP) script into ASP equivalent?

Note: The other sources in PERL and PHP are available at http://www.clickbank.com/crypto.html

Here's the version in C

---START OF CODE---

int valid(char *arg_seed, char *arg_cbpop, char *secret_key)
 // - Pass seed, cbpop, and your key as strings.
 // - Function returns 0 or 1.
 {
    // Copyright Keynetics Inc. Patents pending.
    char a[100], w[100], q[9];
    char *charsmask = "0123456789BCDEFGHJKLMNPQRSTVWXYZ";
    char *p;
    unsigned long int h, l, i, wi, x, y, z, n, s[10];
 
    if (!strcmp(arg_seed, ""))  { return 0; }
    if (!strcmp(arg_cbpop, "")) { return 0; }
 
    h=0x80000000; l=0x7fffffff; strcpy(q, "");
    sprintf(w,"%s %s",secret_key,arg_seed);
 
    p=w; while(*p){*p=toupper(*p);p++;}
    x=y=z=17; n=strlen(w);
 
    for(i=0;i<10;i++){s[i]=0;}
 
    for(i=0;i<256;i++)
      { wi=((x&l)+(y&l))^((x^y)&h);
        wi=(wi<<z)|(wi>>(32-z));
        wi=((wi&l)+w[i%n])^(wi&h);
        s[i&7]+=wi&31;
        z=y&31; y=x; x=wi;
      }
 
    for (i=0; i < 8; i++) { q[i] = charsmask[s[i] & 31]; }
    q[8] = '\0';
 
    if (!strcmp(arg_cbpop, q)) { return 1; }
    else { return 0; }
 }

---END OF CODE ---
0
Comment
Question by:CarMar
  • 11
  • 6
  • 5
22 Comments
 
LVL 19

Expert Comment

by:Dexstar
ID: 9757426
CarMar:

> Hello ASP experts, can somebody translate this C (or PERL or PHP) script into ASP equivalent?

That sort of code doesn't lend itself to VBScript very well.  Maybe you should put that inside of a COM object that you can invoke from ASP, that way you don't have to port the code from C.

Hope That Helps,
Dex*
0
 
LVL 11

Expert Comment

by:Zontar
ID: 9757620
Please post the PHP code.
0
 
LVL 1

Author Comment

by:CarMar
ID: 9757788
Zontar,

You could get it, as I say in the post, on http://www.clickbank.com/crypto.html

Anyway, here's the PHP version of the above code from ClickBank:

---START OF PHP CODE---

function cbValid($seed, $cbpop, $secret_key)
{
  if (! $seed) return 0;
  if (! $cbpop) return 0;
 
  $hh = 0x8000;
  $lh = 0x0000;
  $hl = 0x7fff;
  $ll = 0xffff;
  $charsmask =
  array("0","1","2","3","4","5","6","7",
        "8","9","B","C","D","E","F","G",
        "H","J","K","L","M","N","P","Q",
        "R","S","T","V","W","X","Y","Z");
  for ($i=0;$i<10;$i++) $q[$i]="";
  $w = sprintf("%s %s",$secret_key,$seed);
  $w = strtoupper($w);
  $v = unpack("C*",$w);
  $hx = 0; $lx = 17;
  $hy = 0; $ly = 17;
  $z  =17; $n = strlen($w);
  for ($i=0;$i<10;$i++) $s[$i] = 0;
 
  for($i=0;$i<256;$i++)
  { $tmp1l = $lx & $ll;
    $tmp1h = $hx & $hl;
    $tmp2l = $ly & $ll;
    $tmp2h = $hy & $hl;
    $tmp3l = $tmp1l + $tmp2l;
    $correction = $tmp3l;
    $tmp3l = $tmp3l & 0x0000ffff;
    $correction = $correction - $tmp3l;
    $correction = $correction / pow(2,16);
    $tmp3h = $tmp1h + $tmp2h;
    $tmp3h += $correction;
    $tmp3h = $tmp3h & 0x0000ffff;
    $tmp4l = $lx ^ $ly;
    $tmp4h = $hx ^ $hy;
    $tmp4l = $tmp4l & $lh;
    $tmp4h = $tmp4h & $hh;
    $wil = $tmp3l ^ $tmp4l;
    $wih = $tmp3h ^ $tmp4h;
    $tmp1l = $wil;
    $tmp1h = $wih;
 
    if($z == 32)
    { $tmpl1=0; $tmp1h=0; }
    elseif($z == 16)
    { $tmp1h=$tmp1l; $tmp1l=0; }
    elseif($z > 16)
    { $shiftleft= $z - 16;
      $tmp1h = $tmp1l * pow(2,$shiftleft);
      $tmp1h = $tmp1h & 0x0000ffff;
      $tmp1l = 0;
    }
    else
    {
      $tmp1l = $tmp1l * pow(2,$z);
      $correction = $tmp1l;
      $tmp1l = $tmp1l & 0x0000ffff;
      $correction = $correction - $tmp1l;
      $correction = $correction / pow(2,16);
      $tmp1h = $tmp1h * pow(2,$z);
      $tmp1h += $correction;
      $tmp1h = $tmp1h & 0x0000ffff;
    }
 
    $tmp2l = $wil;
    $tmp2h = $wih;
    $shiftvalue = 32 - $z;
 
    if($shiftvalue == 32)
    { $tmp2l = 0; $tmp2h = 0; }
    elseif($shiftvalue == 16)
    { $tmp2l = $tmp2h; $tmp2h = 0; }
    elseif($shiftvalue > 16)
    { $shiftright = $shiftvalue - 16;
      $tmp2l = $tmp2h >> $shiftright;
      $tmp2h = 0;
    }
    else
    { $tmp2l = ($tmp2l >> $shiftvalue);
      $shiftright = $shiftvalue;
      $bitmask = 1;
 
      for($j=1;$j<$shiftright;$j++)
        $bitmask = $bitmask * 2 + 1;
 
      $correction = ($tmp2h & $bitmask) * pow(2,16 - $shiftvalue);
      $tmp2l += $correction;
      $tmp2h = $tmp2h >> $shiftvalue;
    }
 
    $wil = ($tmp1l | $tmp2l);
    $wih = ($tmp1h | $tmp2h);
    $tmp1l = $wil & $ll;
    $tmp1h = $wih & $hl;
    $tmp1l = $tmp1l + $v[$i%$n + 1];
    $correction = $tmp1l & 0x7fff0000;
    $correction = ($correction >> 16);
    $tmp1h += $correction;
    $tmp1l = $tmp1l & 0x0000ffff;
    $tmp2l = $wil & $lh;
    $tmp2h = $wih & $hh;
    $wil = $tmp1l ^ $tmp2l;
    $wih = $tmp1h ^ $tmp2h;
    $s[$i & 7] += $wil & 31;
    $z = $ly & 31;
    $ly = $lx;
    $hy = $hx;
    $lx = $wil;
    $hx = $wih;
  }
 
  for ($i=0; $i < 8; $i++)
    $q[$i] = $charsmask[$s[$i] & 31];
 
  $q[8] = "\0";
  $finalstring = "";
  for($i=0;$i < 8;$i++)
    $finalstring .= $q[$i];
  if (!strcmp($cbpop, $finalstring)) return 1;
  else return 0;
}

---END OF PHP CODE---
0
 
LVL 11

Expert Comment

by:Zontar
ID: 9757908
Heh, silly me. :)

I'll do you an ASP version, but it'll have to be in JScript. I don't think VBScript will handle the bit-shifting.
0
 
LVL 1

Author Comment

by:CarMar
ID: 9758150
Zontar:

JScript is fine :)
0
 
LVL 19

Expert Comment

by:Dexstar
ID: 9764878
CarMar:

Do you have any sample cases?  Like some inputs to try, and what the result should be?  That will help in testing.

Dex*
0
 
LVL 1

Author Comment

by:CarMar
ID: 9765891
Dexstar:

Here are some results (all TRUE) using two different secret keys.

------------------------------
USING SECRET_KEY: MYPASS
------------------------------
Example 1
----------------
SEED : 41FLZ9FJJ
CBPOP: CNLXRGCV
----------------
Example 2
----------------
SEED : EXPERTS87
CBPOP: MW6RZ7JS
-----------------
Example 3
-----------------
SEED : 123ABC456
CBPOP: 75PFVMSM
-----------------
Example 4
-----------------
SEED : THESEED
CBPOP: 92KFNW7Z
-----------------
Example 5
-----------------
SEED : 1234567890
CBPOP: RZ3Z8YWV


-------------------------------
USING SECRET_KEY: SEC76PU71KY3
-------------------------------
Example 1
-----------------
 SEED : 41FLZ9FJJ
 CBPOP: 2CKNHRP0
-----------------
Example 2
-----------------
 SEED : EXPERTS87
 CBPOP: HPFGYV9M
-----------------
Example 3
-----------------
 SEED : 123ABC456
 CBPOP: 5NWXHLCC
-----------------
Example 4
-----------------
 SEED : THESEED
 CBPOP: JKRR294R
-----------------
Example 5
-----------------
SEED : 1234567890
CBPOP: 5NVESLEH
0
 
LVL 11

Expert Comment

by:Zontar
ID: 9767815
Thanks for the test data.

I've finished a first passat the PHP->JScript conversion and will test with this shortly.

Also, I notice that the funciton returns 1 or 0 -- any reason why this can't be a Boolean True or False instead? (Just wondering...)

cheers

Z.
0
 
LVL 1

Author Comment

by:CarMar
ID: 9767953
Zontar:

> Also, I notice that the funciton returns 1 or 0 -- any reason
> why this can't be a Boolean True or False instead? (Just wondering...)

That's the way ClickBank developed it. If possible return also the same values.

Thanks
Carlos
0
 
LVL 11

Expert Comment

by:Zontar
ID: 9768415
No worries, I've not changed that.

Here's what I've got so far. It's not throwing any errors, but it's not working correctly, either. I changed the structure slightly because it's best practice to have only one return point from a function, but other than that, it should be identical:

<%@LANGUAGE="JSCRIPT"%>
<%
function cbValid(seed, cbpop, secret_key)
{
  var returnVal = 0;

  if(seed && cbpop)
  {
    var hh = 0x8000;
    var lh = 0x0000;
    var hl = 0x7fff;
    var ll = 0xffff;
    var charsmask = ["0","1","2","3","4","5","6","7",
                     "8","9","B","C","D","E","F","G",
                     "H","J","K","L","M","N","P","Q",
                     "R","S","T","V","W","X","Y","Z"];

    var q = new Array();
    for(var i = 0; i < 10; i++)
      q[i] = "";

    var w = (secret_key + " " + seed).toUpperCase();
    var n = w.length;
    var v = new Array();
    for(var i = 0; i < n; i++);
      v[i] = w.charCodeAt(i);

    var hx = 0;
    var hy = 0;
    var lx = 17;
    var ly = 17;
    var z = 17;

    var s = new Array();
    for(var i = 0; i < 10; i++)
      s[i] = 0;

    for(var i = 0; i < 256; i++)
    {
      tmp1l = lx & ll;
      tmp1h = hx & hl;
      tmp2l = ly & ll;
      tmp2h = hy & hl;
      tmp3l = tmp1l + tmp2l;
      correction = tmp3l;
      tmp3l &= 0x0000ffff;
      correction -= tmp3l;
      correction /= Math.pow(2, 16);
      tmp3h = tmp1h + tmp2h;
      tmp3h += correction;
      tmp3h &= 0x0000ffff;
      tmp4l = lx ^ ly;
      tmp4h = hx ^ hy;
      tmp4l &= lh;
      tmp4h &= hh;
      wil = tmp3l ^ tmp4l;
      wih = tmp3h ^ tmp4h;
      tmp1l = wil;
      tmp1h = wih;

      if(z == 32)
      {
        tmpl1 = 0;
        tmp1h = 0;
      }
      else
      {
        if(z == 16)
        {
          tmp1h = tmp1l;
          tmp1l = 0;
        }
        else
        {
          if(z > 16)
          {
            shiftleft = z - 16;
            tmp1h = tmp1l * Math.pow(2, shiftleft);
            tmp1h &= 0x0000ffff;
            tmp1l = 0;
          }
          else
          {
            tmp1l *= Math.pow(2, z);
            correction = tmp1l;
            tmp1l &= 0x0000ffff;
            correction -= tmp1l;
            correction /= Math.pow(2, 16);
            tmp1h *= Math.pow(2, z);
            tmp1h += correction;
            tmp1h &= 0x0000ffff;
          }
        }
      }

      tmp2l = wil;
      tmp2h = wih;
      shiftvalue = 32 - z;

      if(shiftvalue == 32)
      {
        tmp2l = 0;
        tmp2h = 0;
      }
      else
      {
        if(shiftvalue == 16)
        {
          tmp2l = tmp2h;
          tmp2h = 0;
        }
        else
        {
          if(shiftvalue > 16)
          {
            shiftright = shiftvalue - 16;
            tmp2l = tmp2h >> shiftright;
            tmp2h = 0;
          }
          else
          {
            tmp2l >>= shiftvalue;
            shiftright = shiftvalue;
            bitmask = 1;

            for(var j = 1; j < shiftright; j++)
              bitmask = bitmask * 2 + 1;

            correction = (tmp2h & bitmask) * Math.pow(2, 16 - shiftvalue);
            tmp2l += correction;
            tmp2h >>= shiftvalue;
          }
        }
      }

      wil = tmp1l | tmp2l;
      wih = tmp1h | tmp2h;
      tmp1l = wil & ll;
      tmp1h = wih & hl;
      tmp1l += v[(i % n) + 1];
      correction = tmp1l & 0x7fff0000;
      correction >>= 16;
      tmp1h += correction;
      tmp1l &= 0x0000ffff;
      tmp2l = wil & lh;
      tmp2h = wih & hh;
      wil = tmp1l ^ tmp2l;
      wih = tmp1h ^ tmp2h;
      s[i & 7] += wil & 31;
      z = ly & 31;
      ly = lx;
      hy = hx;
      lx = wil;
      hx = wih;
    }

    for(var i = 0; i < 8; i++)
      q[i] = charsmask[s[i] & 31];

    q[8] = "\0";

    var finalstring = "";

    for(var i = 0; i < 8; i++)
      finalstring += q[i] + "";

    if(cbpop == finalstring)
      returnVal = 1;
  }

  return returnVal;
}

//  TESTING...

Response.write("<p>" + cbValid("EXPERTS87", "MW6RZ7JS", "MYPASS") + "</p>");

Response.write("<p>" + cbValid("123ABC456", "75PFVMSM", "MYPASS") + "</p>");

Response.write("<p>" + cbValid("THESEED", "92KFNW7Z", "MYPASS") + "</p>");

%>

All of the hexadecimal arithmetic should would the same, and my replacement for the PHP unpack() call appears to function correctly (JS doesn't have an equivalent). (Note: I'm aware that unpack() has a lot of other parameters that can be passed to it, and this is only intended to replace unpack("C*", $some_string).)

The shortcut assignment operators are legal in JS for all arithmetic and logical operators -- for example,

val1 &= val2;
val3 >>= val4;

should have exactly the same effect as

val1 = val1 & val2;
val3 = val3 >> val4;

The only other thing I can think of is that I've nested the if/else's incorrectly or made a typo (the cryptic variable names with lots of i's, 1's and l's don't help). Can anybody spot anything like that?
0
 
LVL 1

Author Comment

by:CarMar
ID: 9888166
Ok, I've raised more 500 points to see if someone provides me a working solution.

Thanks
CarMar
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 11

Expert Comment

by:Zontar
ID: 9889525
Well, if someone could just eyeball my script and point out where I've messed up, that'd probably do it. I'm pretty sure it's just a silly typo or somesuch, but damned if I can find it.
0
 
LVL 19

Expert Comment

by:Dexstar
ID: 9890302
@Zontar : I think there may be more to it than that.  For starters, the ^ operator in C means XOR, not Power.  I don't know why you need to call the Pow function at all.

@CarMar : I couldn't get JScript to do the math correctly.  It gets it right for the first 8 or 9 steps in the loop, then some negative values come up that through off the calculation.  I don't know JScript well enought to force it to treat everything as unsigned.

It would be trivial to wrap that code inside of a COM object that you could invoke from your ASP.  You'd just have to register a DLL on the web server before doing it.  Would you accept that as a solution if I wrote the COM object for you?  You could compile the source or I could compile it and post it on a web site, and you could download it.

Dex*
0
 
LVL 19

Expert Comment

by:Dexstar
ID: 9890314
Here is the JScript that I have so far...  Maybe someone else can figure out how to make it so it treats signed values the same way as C does.

      function valid(seed, cbpop, secret_key)
      {
            if ( !seed || !cbpop )
            {
                  return 0;
            }
            
            var w, q;
            var charsmask = ["0","1","2","3","4","5","6","7",
                                       "8","9","B","C","D","E","F","G",
                        "H","J","K","L","M","N","P","Q",
                               "R","S","T","V","W","X","Y","Z"];
            var h, l, i, wi, x, y, z, n, s;
            
            h = 0x80000000;
            l = 0x7fffffff;
            w = (secret_key + " " + seed).toUpperCase();
            x = y = z = 17;
            n = w.length;
            s = new Array(10);
            
            for(i=0;i<10;i++) {s[i]=0;}
            
            var temp;

            for(i=0;i<256;i++)
            {
                  wi=((x&l)+(y&l))^((x^y)&h);
                  wi=(wi<<z)|(wi>>(32-z));
                  wi=((wi&l)+w.charCodeAt(i%n))^(wi&h);
                  s[i&7]+=wi&31;
                  z=y&31; y=x; x=wi;
            }

            q = "";
            for ( i=0; i<8; i++ )
            {
                  q = q + charsmask[s[i] & 31];
            }
            
            return (cbpop == q) ? 1 : 0;
      }
0
 
LVL 11

Expert Comment

by:Zontar
ID: 9890672
>  For starters, the ^ operator in C means XOR, not Power.  I don't know why you need to call the Pow function at all.

What on earth would make you think that I'm confusing the ^ operator with powers?

I'm working from the PHP version, which has:

$correction = $correction / pow(2,16);  // "$correction equals $correction divided by 2 to the 16th power"

The JS version of this would be:

correction /= Math.pow(2, 16);  // "correction equals correction divided by 2 to the 16th power"

>  I couldn't get JScript to do the math correctly.  It gets it right for the first 8 or 9 steps in the loop, then some negative values come up that through off the calculation.  I don't know JScript well enought to force it to treat everything as unsigned.

JS does 32-bit math, so all of the values should be handled correctly. (Sign changes usually indicate that the limit has been exceeded).

Evidently it's either the magnitude problem that you've reported or else I've made an error somewhere in trying to optimise the function a bit as I went. I'm going to start over, and follow the logic of the PHP version exactly this time. Code to follow shortly.
0
 
LVL 11

Expert Comment

by:Zontar
ID: 9890786
Okay, this is as near to *exact* translation of the PHP code as can be done. I've taken no shortcuts, changed no ordering, etc.

<%@LANGUAGE="JSCRIPT"%>
<%
function cbValid(seed, cbpop, secret_key)
{
  if(!seed)
    return 0;
  if(!cbpop)
    return 0;

  hh = 0x8000;
  lh = 0x0000;
  hl = 0x7fff;
  ll = 0xffff;
 
  charsmask = [ "0","1","2","3","4","5","6","7",
                "8","9","B","C","D","E","F","G",
                "H","J","K","L","M","N","P","Q",
                "R","S","T","V","W","X","Y","Z"
              ];
             
  q = new Array();
  for(i = 0; i < 10; i++)
    q[i] = "";

  w = (secret_key + " " + seed).toUpperCase();
 
  v = new Array();
  for(var i = 0; i < w.length; i++);
    v[i] = w.charCodeAt(i);

  hx = 0;
  lx = 17;
  hy = 0;
  ly = 17;
  z  = 17;
  n = w.length;
 
  s = new Array();
  for(i = 0; i < 10; i++)
    s[i] = 0;

  for(i = 0; i < 256; i++)
  {
    tmp1l = lx & ll;
    tmp1h = hx & hl;
    tmp2l = ly & ll;
    tmp2h = hy & hl;
    tmp3l = tmp1l + tmp2l;
    correction = tmp3l;
    tmp3l = tmp3l & 0x0000ffff;
    correction = correction - tmp3l;
    correction = correction / Math.pow(2,16);
    tmp3h = tmp1h + tmp2h;
    tmp3h += correction;
    tmp3h = tmp3h & 0x0000ffff;
    tmp4l = lx ^ ly;
    tmp4h = hx ^ hy;
    tmp4l = tmp4l & lh;
    tmp4h = tmp4h & hh;
    wil = tmp3l ^ tmp4l;
    wih = tmp3h ^ tmp4h;
    tmp1l = wil;
    tmp1h = wih;

    if(z == 32)
    {
      tmpl1 = 0;
      tmp1h = 0;
    }
    else
    {
      if(z == 16)
      {
        tmp1h = tmp1l;
        tmp1l = 0;
      }
      else
      {
        if(z > 16)
        {
          shiftleft= z - 16;
          tmp1h = tmp1l * Math.pow(2, shiftleft);
          tmp1h = tmp1h & 0x0000ffff;
          tmp1l = 0;
        }
        else
        {
          tmp1l = tmp1l * Math.pow(2, z);
          correction = tmp1l;
          tmp1l = tmp1l & 0x0000ffff;
          correction = correction - tmp1l;
          correction = correction / Math.pow(2, 16);
          tmp1h = tmp1h * Math.pow(2, z);
          tmp1h += correction;
          tmp1h = tmp1h & 0x0000ffff;
        }
      }
    }

    tmp2l = wil;
    tmp2h = wih;
    shiftvalue = 32 - z;

    if(shiftvalue == 32)
    {
      tmp2l = 0;
      tmp2h = 0;
    }
    else
    {
      if(shiftvalue == 16)
      {
        tmp2l = tmp2h;
        tmp2h = 0;
      }
      else
      {
        if(shiftvalue > 16)
        {
          shiftright = shiftvalue - 16;
          tmp2l = tmp2h >> shiftright;
          tmp2h = 0;
        }
        else
        {
          tmp2l = (tmp2l >> shiftvalue);
          shiftright = shiftvalue;
          bitmask = 1;

          for(j = 1; j < shiftright; j++)
            bitmask = bitmask * 2 + 1;

          correction = (tmp2h & bitmask) * Math.pow(2, 16 - shiftvalue);
          tmp2l += correction;
          tmp2h = tmp2h >> shiftvalue;
        }
      }
    }

    wil = (tmp1l | tmp2l);
    wih = (tmp1h | tmp2h);
    tmp1l = wil & ll;
    tmp1h = wih & hl;
    tmp1l = tmp1l + v[i%n + 1];
    correction = tmp1l & 0x7fff0000;
    correction = (correction >> 16);
    tmp1h += correction;
    tmp1l = tmp1l & 0x0000ffff;
    tmp2l = wil & lh;
    tmp2h = wih & hh;
    wil = tmp1l ^ tmp2l;
    wih = tmp1h ^ tmp2h;
    s[i & 7] += wil & 31;
    z = ly & 31;
    ly = lx;
    hy = hx;
    lx = wil;
    hx = wih;
  }

  for(i = 0; i < 8; i++)
    q[i] = charsmask[s[i] & 31];

  q[8] = "\0";
  finalstring = "";
 
  for(i = 0; i < 8; i++)
    finalstring += q[i];
   
  if(cbpop == finalstring)
    return 1;
  else
    return 0;
}

//  TESTING...

Response.write("<p>" + cbValid("EXPERTS87", "MW6RZ7JS", "MYPASS") + "</p>");

Response.write("<p>" + cbValid("123ABC456", "75PFVMSM", "MYPASS") + "</p>");

Response.write("<p>" + cbValid("THESEED", "92KFNW7Z", "MYPASS") + "</p>");

%>

Evidently it's in the math handling somewhere.

I'm not much of a C programmer, but I'm gonna try working from the C source instead.
0
 
LVL 11

Accepted Solution

by:
Zontar earned 250 total points
ID: 9890885
*S*U*C*C*E*S*S

:D

Here's the working JScript/ASP function:

<%@LANGUAGE="JSCRIPT"%>
<%
function cbValid(seed, cbpop, secret_key)
{
  if( !seed || !cbpop )
    return 0;
 
  var w, q;
  var charsmask = "0123456789BCDEFGHJKLMNPQRSTVWXYZ";
  var h, l, i, wi, x, y, z, n, s;
 
  h = 0x80000000;
  l = 0x7fffffff;
  w = (secret_key + " " + seed).toUpperCase();
  x = y = z = 17;
  n = w.length;
  s = new Array(10);
 
  for(i = 0; i < 10; i++)
    s[i] = 0;
 
  var temp;
 
  for(i = 0; i < 256; i++)
  {
    wi = ((x & l) + (y & l)) ^ ((x ^ y) & h);
    wi = (wi << z) | (wi >>> (32-z));
    wi = ((wi&l) + w.charCodeAt(i % n)) ^ (wi & h);
    s[i & 7] += wi & 31;
    z = y & 31; y = x; x = wi;
  }
 
  q = "";
 
  for(i = 0; i < 8; i++)
    q = q + charsmask.charAt(s[i] & 31);
 
  return (cbpop == q) ? 1 : 0;
}


//  TESTING...

Response.write("<p>" + cbValid("EXPERTS87", "MW6RZ7JS", "MYPASS") + "</p>");

Response.write("<p>" + cbValid("123ABC456", "75PFVMSM", "MYPASS") + "</p>");

Response.write("<p>" + cbValid("THESEED", "92KFNW7Z", "MYPASS") + "</p>");

%>

Explanation in following post.
0
 
LVL 11

Expert Comment

by:Zontar
ID: 9890925
First, I would like to thank Dexstar for giving me a couple of clues that I needed.

1) I dropped the PHP code and worked from the C code, which is MUCH shorter and more to the point, double-checking against Dexstar's translation attempt and borrowing from it in a couple of places, since my C is pretty weak (I took a couple of semesters of C and C++ in school and did quite well, but that was nearly 4 years ago, and I've not touched it since).

2) I figured out what was up with the signed/unsigned numbers. It has to do with how JS handles bit-shifting. In JS, the >> operator is a right-shift *with sign*; it sets ones in the high bits of the result if the original left-hand-side was less than zero. In order to do *unsigned* bit-shifting, one needs to use the >>> operator, which sets zeroes for any bits shifted in, regardless of the sign. Changing the line

wi = (wi << z) | (wi >> (32-z));

to

wi = (wi << z) | (wi >>> (32-z));

did the trick.

This has been bugging me for two weeks now.

Hooray.
0
 
LVL 19

Assisted Solution

by:Dexstar
Dexstar earned 250 total points
ID: 9891347
ARGH!  You mean I spent 4 hours trying to get JScript to work and all I needed was ONE SINGLE STUPID GREATER THAN SYMBOL!?!?

@Zontar : Thank you!  This is a perfect example of how powerful this web site can be in terms of collaborative efforts.  My suggestion for a COM object was out desparation to provide an answer.  I knew the JScript *should* be sufficient, but couldn't make it work.  I've never even heard of the >>> operator.

I knew that line was the offending line too because I printed out the value at each step in both the C and JScript versions, and that was the line where they would start to have different outputs.

Please pardon my snide remark earlier.  I thought your JScript conversion was a little out there, but I didn't even look at the PHP version (I never touch the stuff..  Look how much more code it took to do it in PHP compared to C and JScript!).  I was wondering what you were doing since you can practically copy and paste the C version and tweak it a little.  Splitting up those constants into 2 values!?  But I totally get it now.  :)

Speaking of copy and paste, you should remove this line from your code:
 var temp;

It is left over from my debugging code, and I forgot to take it out before posting.  Also, I noticed you changed these lines:
     var charsmask = "0123456789BCDEFGHJKLMNPQRSTVWXYZ";
And
     q = q + charsmask.charAt(s[i] & 31);

I like that implementation much better.  But, the one that I used, I stole from your PHP attempt, so...  :)

Well, this was my first attempt with anything JScript.  It was fun, but frustrating to get so close, and be so far off.  I'm glad you got it working!

Dex*
0
 
LVL 11

Expert Comment

by:Zontar
ID: 9891433
> ARGH!  You mean I spent 4 hours trying to get JScript to work and all I needed was ONE SINGLE STUPID GREATER THAN SYMBOL!?!?

Is there an echo in here, man? <G>

> I knew that line was the offending line too because I printed out the value at each step in both the C and JScript versions, and that was the line where they would start to have different outputs.

After I went to the C code and your example, I made the same discovery. I started asking myself, "Ohhhkaaayyyeeee... When is a bit-shift *not* a bit-shift...?" and started digging through a couple of references.

> Speaking of copy and paste

Busted! Heheh.

> Look how much more code it took to do it in PHP compared to C and JScript!

Yeah, my teeth about fell out when I looked at the C and Perl versions and then back at the PHP code. Alas, it turns out that there are major issues with unisgned integers in PHP, and there are no plans to fix this -- the official line is, "This is not a bug. If this is a problem for you, you can go get the source for the GMP libraries at www.swox.com/gmp and compile them yourself."

Next time, I'll not be so nervous about working from C source.

And yes, collaboration is a Very Cool Thing(TM). Thanks for the help.
0
 
LVL 1

Author Comment

by:CarMar
ID: 9891614
Zontar:
Thanks for your solution!
I've just created a "Points For" question for you to award more 500 points for this solution and persistence to solve this. You can get your extra points at:
http://www.experts-exchange.com/Web/Web_Languages/ASP/Q_20818678.html

Dextar:
Thanks also for your help in solving this.

Note: I'm going to split the points of this question for both of you.

Once again, thanks for your help.
Carlos
0
 
LVL 11

Expert Comment

by:Zontar
ID: 9891740
No woriies, I'm just glad we finally got this sorted -- it was really starting to drive me crazy!
0

Featured Post

Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

Join & Write a Comment

Have you ever needed to get an ASP script to wait for a while? I have, just to let something else happen. Or in my case, to allow other stuff to happen while I was murdering my MySQL database with an update. The Original Issue This was written…
I was asked about the differences between classic ASP and ASP.NET, so let me put them down here, for reference: Let's make the introductions... Classic ASP was launched by Microsoft in 1998 and dynamically generate web pages upon user interact…
Excel styles will make formatting consistent and let you apply and change formatting faster. In this tutorial, you'll learn how to use Excel's built-in styles, how to modify styles, and how to create your own. You'll also learn how to use your custo…
This tutorial demonstrates a quick way of adding group price to multiple Magento products.

707 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

17 Experts available now in Live!

Get 1:1 Help Now