Solved

Function not working properly in PHP vs JS

Posted on 2012-04-01
13
310 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 83

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 83

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
NAS Cloud Backup Strategies

This article explains backup scenarios when using network storage. We review the so-called “3-2-1 strategy” and summarize the methods you can use to send NAS data to the cloud

 

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
 
LVL 83

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 83

Expert Comment

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

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This script checks a path to see if a folder exists. If the folder does exist you will get output "The folder has previously been created. No action taken" If not it will create the folder. Then adds one user modify permission to the folder. It …
Boost your ability to deliver ambitious and competitive web apps by choosing the right JavaScript framework to best suit your project’s needs.
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 dynamically set the form action using jQuery.

839 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