Solved

Function not working properly in PHP vs JS

Posted on 2012-04-01
13
306 Views
Last Modified: 2012-04-03
Hi, We have a function in JS that we are trying to recreate in PHP however the results seem to be inconsistent and don't always match the output from JS. I would appreciate any feedback anyone might be able to give to what the problem might be. Below are the functions and some sample output results.

Thanks in advance

The JS function:

function GenerateVoucherPIN(artwork_code, voucher_number)
{
var a = 43003;
var b = 65536;
var c = 571;
var hash = 0;
var voucher_code = voucher_number + artwork_code;
for (i = 0; i < voucher_code.length; i++)
{
hash = (hash * a * voucher_code.charCodeAt(i) + c) % b;
c = Math.floor((a * hash + c) / b);
}
return hash % 10000;
}


Our PHP function:

function charCodeAt($str, $i){
      return ord(substr($str, $i, 1));
}
function GenerateVoucherPIN($voucher_number,$artwork_code)
{
      $a = 43003;
      $b = 65536;
      $c = 571;
      $hash = 0;
      
      $voucher_number = intval($voucher_number);
      $voucher_code = $voucher_number . $artwork_code;
      for ($i = 0; $i < strlen($voucher_code); $i++)
      {
            $hash = bcmod($hash * $a * charCodeAt($voucher_code,$i) + $c, $b)      ;
            $c = floor(($a * $hash + $c) / $b);
      }
      $result = str_pad($hash % 10000, 4, 0, STR_PAD_LEFT);//Pad with 0 to get a four digit value
      return $result;
}

GenerateVoucherPIN(0001341,'FTR');
GenerateVoucherPIN('0001341','FTR');

Below are some sample output results comparing PHP and JS. We have tried both as an integer and as a string.

Voucher Number (String Format)     PIN Number (PHP)    PIN Number (JS)
'0001341'           0805       8716
'0020448'           7164       7164
'0054695'           4681       4681
'0009997'           8111       8111
'0018001'           2851       2851
'0000401'           0062       3345
'0010177'           4792       2281

Voucher Number (Integer Format)    PIN Number (PHP)     PIN Number (JS)
0001341     8716       8716
0020448     7535       7164
0054695     1159       4681
0009997     7298       8111
0018001     3977       2851
0000401     3345       3345
0010177     2281       2281
0
Comment
Question by:LetsLearn
  • 7
  • 4
  • 2
13 Comments
 
LVL 82

Expert Comment

by:Dave Baldwin
ID: 37794414
I put it all in one page and I'm not getting what you are getting.  

This is my results:
_Code__ _PHP _jscript

0001341 0805 6000
0020448 5206 4058
0054695 5140 2206
0009997 4306 1693
0018001 0601 2364
0000401 8214 6053
0010177 7700 4185

Open in new window



And this is the code I copied from above:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
 "http://www.w3.org/TR/html4/loose.dtd">

<html>
<head>
<title>Untitled</title>
<script type="text/javascript">
<!--
function GenerateVoucherPIN(artwork_code, voucher_number)
{
var a = 43003;
var b = 65536;
var c = 571;
var hash = 0;
var voucher_code = voucher_number + artwork_code;
for (i = 0; i < voucher_code.length; i++)
{
hash = (hash * a * voucher_code.charCodeAt(i) + c) % b;
c = Math.floor((a * hash + c) / b);
}
return hash % 10000;
}

// -->
</script>
</head>
<body>
<pre>
_Code__ _PHP _jscript<br>
<?php 
function charCodeAt($str, $i){
      return ord(substr($str, $i, 1));
}
function GenerateVoucherPIN($voucher_number,$artwork_code)
{
      $a = 43003;
      $b = 65536;
      $c = 571;
      $hash = 0;
      
      $voucher_number = intval($voucher_number);
      $voucher_code = $voucher_number . $artwork_code;
      for ($i = 0; $i < strlen($voucher_code); $i++)
      {
            $hash = bcmod($hash * $a * charCodeAt($voucher_code,$i) + $c, $b)      ;
            $c = floor(($a * $hash + $c) / $b);
      }
      $result = str_pad($hash % 10000, 4, 0, STR_PAD_LEFT);//Pad with 0 to get a four digit value
      return $result;
}
$tstcodes = array('0001341','0020448','0054695','0009997','0018001','0000401','0010177');
foreach($tstcodes as $val) {
	echo $val." ".GenerateVoucherPIN($val,'FTR')." <script type='text/javascript'>document.write(GenerateVoucherPIN('$val','FTR'));</script><br>";
	}
 ?>
 
</pre>
</body>
</html>

Open in new window

0
 

Author Comment

by:LetsLearn
ID: 37794428
Hi Dave,

I probably should have added a couple of details in the above question - there is an artwork code of 3 letters. The artwork code is added to the sequence prior to the serial number. Not sure if this is why you are getting different results.

What we are trying to generate is 4 number security number for a product. We need to use the function in one area in JS and in another in PHP.

Thanks Cat
0
 
LVL 82

Expert Comment

by:Dave Baldwin
ID: 37794447
I understand what you are trying to do.  But the code you have posted does not give the results that you showed.  That makes it difficult for us to help you.  As far as I can tell, I copied your code correctly and then added a section to the PHP code to run thru the values you have posted.  But it's not matching up.  ??
0
 

Author Comment

by:LetsLearn
ID: 37794460
Hmmm let me check
0
 

Author Comment

by:LetsLearn
ID: 37794622
Hi Dave,

Attached is a  PHP file with both the JS and PHP functions. We have added two voucher numbers as an example. For first voucher number, the integer value output is same as JS output. And for second example, the string value output is same as the JS output.

But it doesn't always give consistent results. Hope this helps clarify what we have at the moment.

Any feedback would be most welcome.

Thanks Cat
0
 

Author Comment

by:LetsLearn
ID: 37794623
And the attachment!
Genpin.php
0
6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

 
LVL 82

Accepted Solution

by:
Dave Baldwin earned 500 total points
ID: 37794735
I got it so it works with strings.  I don't think it will work passing numbers because PHP comes up with something different than javascript.  In your original post above, you were passing the parameters to the JS and the PHP in the opposite order which meant they would never agree.  In addition, the 'intval' statement in the PHP section was changing the $voucher_number to something unusable.

You can see some of the commented out statements that I used to test the code in the attached file.
Genpin2.php
0
 

Author Comment

by:LetsLearn
ID: 37794738
Thanks Dave I'll take a look now
0
 
LVL 10

Expert Comment

by:MadShiva
ID: 37795074
Dear, I have test and the fonction charCodeAt in php have some bug.

If you look the char, you see clairly that there's a bug ( one char is missing on php) I think because of the split 0020448 have one more number maybe the problem doesn't occur with other number that contain a even number ex : 120448.


charCodeAt !!! :::: 55
charCodeAt !!! :::: 51
charCodeAt !!! :::: 55
charCodeAt !!! :::: 70
charCodeAt !!! :::: 84
charCodeAt !!! :::: 82
JS PIN Output for 0001341 :::: 8716
charCodeAt !!! :::: 50
charCodeAt !!! :::: 48
charCodeAt !!! :::: 52
charCodeAt !!! :::: 52
charCodeAt !!! :::: 56
charCodeAt !!! :::: 85
charCodeAt !!! :::: 65
JS PIN Output for 0020448 :::: 7164

PHP charCodeAt !!!!!!!!! 55
PHP charCodeAt !!!!!!!!! 51
PHP charCodeAt !!!!!!!!! 55
PHP charCodeAt !!!!!!!!! 70
PHP charCodeAt !!!!!!!!! 84
PHP charCodeAt !!!!!!!!! 82
PHP PIN Output (Integer) for 0001341 :::: 8716

PHP charCodeAt !!!!!!!!! 49
PHP charCodeAt !!!!!!!!! 48
PHP charCodeAt !!!!!!!!! 54
PHP charCodeAt !!!!!!!!! 48
PHP charCodeAt !!!!!!!!! 85
PHP charCodeAt !!!!!!!!! 65
PHP PIN Output (Integer) for 0020448 :::: 7535

Open in new window


Hope that help you :)
0
 
LVL 10

Expert Comment

by:MadShiva
ID: 37795317
Yes, got it working :)

If you have any question don't hesitate to ask.

Regards
Genpin.php
0
 

Author Comment

by:LetsLearn
ID: 37798796
Thanks MadShiva I'll have a look at this today and let you know how we get on. Thanks so much for your help.
0
 

Author Closing Comment

by:LetsLearn
ID: 37804294
Thanks Dave, we found what you said was absolutely correct. The only way we could match the outputs was to pass the parameters as strings.
0
 
LVL 82

Expert Comment

by:Dave Baldwin
ID: 37804322
You're welcome, glad to help.  It was an interesting question.
0

Featured Post

What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

Developers of all skill levels should learn to use current best practices when developing websites. However many developers, new and old, fall into the trap of using deprecated features because this is what so many tutorials and books tell them to u…
JavaScript can be used in a browser to change parts of a webpage dynamically. It begins with the following pattern: If condition W is true, do thing X to target Y after event Z. Below are some tips and tricks to help you get started with JavaScript …
Learn how to match and substitute tagged data using PHP regular expressions. Demonstrated on Windows 7, but also applies to other operating systems. Demonstrated technique applies to PHP (all versions) and Firefox, but very similar techniques will w…
The viewer will learn how to count occurrences of each item in an array.

706 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

19 Experts available now in Live!

Get 1:1 Help Now