2014-02-17 49 views
1

我需要能夠根據他們的支票號碼驗證CUSIP號碼。感謝維基百科,我擁有該過程的psudocode,但我迄今無法在PHP中複製它。PHP CUSIP支票號碼

可以找到Psudocode 。

我的PHP:

<?php 
/** 
    * function to return the check digit value of a cusip 
    * @param $cusip 
    *  the cusip for processing. 
    * @return Int 
    *  cusip check digit. 
    */ 
    function cusip_checksum($cusip){ 
     $sum = 0; 
     $rebuiltcusip = ''; 
     for($i = 1; $i <= 8; $i++){ 
      $c = substr($cusip, ($i - 1), 1); //$i needs to be 0, so as we start at 1, take 1 off. 
      $rebuiltcusip .= $c; 
      switch(true){ 
       case $c == '0': // ctype_digit(0) returns false, so checking for 0 here. 
        $v = $c; 
        watchdog("case 0: ", $v); 
       break; 
       case ctype_digit($c): //check if numeric 
        $v = $c; 
        watchdog("case ctype_digit: ", $v); 
       break; 
       case $c == '*': 
        $v = 36; 
        watchdog("case *: ", $v); 
       break; 
       case $c == '@': 
        $v = 37; 
        watchdog("case @: ", $v); 
       break; 
       case $c == '#': 
        $v = 38; 
        watchdog("case #: ", $v); 
       break; 
       case !ctype_digit($c): //check letter last as this check would pass with * @ or # so allow them to be checked first 
        $v = (ord($c) - 64) + 9; //set ordinal number, -64 as this returns ASKII value, then add 9. 
        watchdog("case not ctype_digit: ", $v); 
       break; 
      } 
      if(($i % 2) == 0){ //check if odd 
       $v = $v * 2; 
       watchdog("case odd: ", $v); 
      } 

      $sum = $sum + ($v/10) + ($v % 10); 
      watchdog("sum end loop: ", $sum); 
     } 

     $ncd = (10 - ($sum % 10)) % 10; 
     $rebuiltcusip .= $ncd; 
     watchdog("rebuilt cusip: ", "Cusip: ".$cusip." Rebuilt: ".$rebuiltcusip); 
     return $ncd; 
    } 
?> 

看門狗只是我記錄的過程。

通過CUSIP:98986T108,其校驗位值爲8,實際返回值爲98986T104(校驗位值爲4)。

這樣:

<?php 
    print cusip_checksum('98986T108'); 
?> 

應該返回8,它返回4

任何人都可以發現這樣做的原因是什麼?

+1

你必須改變'如果(($ V%2)== 0)''到IF(($ C%2)== 0)' – hindmost

+0

實際上應該是如果(($ I 2% )== 0)而不是$ c,但在那裏非常好。將測試 – tobynew

+0

作出更改,仍然得到不正確的值。 98986T108現在返回4而不是8 – tobynew

回答

1

裹在地板()函數的劃分和你在那裏:

$sum = $sum + floor($v/10) + ($v % 10); 

現在在CUSIP問答將有26的值,這將增加2和6至$總和,而不是加上2.6和6.

下面是修正的最終功能。我通過路透社17614 CUSIPs的摘錄運行了這個,有11個沒有匹配。這與我通常從路透數據中看到的錯誤水平有關,所以我對日常工作有信心。

/** 
* function to return the check digit value of a cusip 
* @param $cusip 
*  the cusip for processing. 
* @return Int 
*  cusip check digit. 
*/ 
function cusip_checksum($cusip){ 
    $sum = 0; 
    $rebuiltcusip = ''; 
    for($i = 1; $i <= 8; $i++){ 
     $c = substr($cusip, ($i - 1), 1); //$i needs to be 0, so as we start at 1, take 1 off. 
     $rebuiltcusip .= $c; 
     switch(true){ 
      case $c == '0': // ctype_digit(0) returns false, so checking for 0 here. 
       $v = $c; 
       watchdog("case 0: ", $v); 
      break; 
      case ctype_digit($c): //check if numeric 
       $v = $c; 
       watchdog("case ctype_digit: ", $v); 
      break; 
      case $c == '*': 
       $v = 36; 
       watchdog("case *: ", $v); 
      break; 
      case $c == '@': 
       $v = 37; 
       watchdog("case @: ", $v); 
      break; 
      case $c == '#': 
       $v = 38; 
       watchdog("case #: ", $v); 
      break; 
      case !ctype_digit($c): //check letter last as this check would pass with * @ or # so allow them to be checked first 
       $v = (ord($c) - 64) + 9; //set ordinal number, -64 as this returns ASKII value, then add 9. 
       watchdog("case not ctype_digit: ", $v); 
      break; 
     } 
     if(($i % 2) == 0){ //check if odd 
      $v = $v * 2; 
      watchdog("case odd: ", $v); 
     } 

     $sum = $sum + floor($v/10) + ($v % 10); 
     watchdog("sum end loop: ", $sum); 
    } 

    $ncd = (10 - ($sum % 10)) % 10; 
    $rebuiltcusip .= $ncd; 
    watchdog("rebuilt cusip: ", "Cusip: ".$cusip." Rebuilt: ".$rebuiltcusip); 
    return $ncd; 
} 
+0

已被接受,我完全忘記了這麼做,所以在回顧過去的Q / – tobynew