Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/291.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php LuhnCalc和bpay MOD10版本5_Php_Payment_Credit Card_Luhn - Fatal编程技术网

Php LuhnCalc和bpay MOD10版本5

Php LuhnCalc和bpay MOD10版本5,php,payment,credit-card,luhn,Php,Payment,Credit Card,Luhn,我使用以下PHP代码计算BPay的CRN: <?php function LuhnCalc($number) { $chars = array_reverse(str_split($number, 1)); $odd = array_intersect_key($chars, array_fill_keys(range(1, count($chars), 2), null)); $even = array_intersect_key($chars, array_fill_key

我使用以下PHP代码计算BPay的CRN:

<?php
function LuhnCalc($number) {
  $chars = array_reverse(str_split($number, 1));
  $odd = array_intersect_key($chars, array_fill_keys(range(1, count($chars), 2), null));
  $even = array_intersect_key($chars, array_fill_keys(range(0, count($chars), 2), null));
  $even = array_map(function($n) { return ($n >= 5)?2 * $n - 9:2 * $n; }, $even);
  $total = array_sum($odd) + array_sum($even);
  return ((floor($total / 10) + 1) * 10 - $total) % 10;
}
print LuhnCalc($_GET['num']);
?>
如您所见,它们都与BPAY编号不匹配。

这是在C#中,但这是我到目前为止为BPAY校验位生成所做的:

private void btnBPayGenerate_Click(object sender, EventArgs e)
{
    var originalChars = txtBPayNumber.Text.ToCharArray();
    List<int> oddDigits = new List<int>();
    List<int> evenDigits = new List<int>();
    int oddTotal = 0, evenTotal = 0, total = 0, checkDigit ;

    const int oddMultiplier = 3;
    const int modulus = 10;
    bool isOdd = true;
    for (int x = 0; x < originalChars.Length; x++)
    {
        if(isOdd)
                oddDigits.Add(Int32.Parse(originalChars[x].ToString()));
            else
                evenDigits.Add(Int32.Parse(originalChars[x].ToString()));
            isOdd = !isOdd;
        }

        foreach (var digit in oddDigits)
            oddTotal += digit;

        foreach (var digit in evenDigits)
            evenTotal += digit;

        oddTotal = oddTotal * oddMultiplier;

        total = oddTotal + evenTotal;

        checkDigit = (modulus - (total % modulus));
lblBPayResult.Text = txtBPayNumber.Text + checkDigit.ToString();
}
private void btnBPayGenerate\u单击(对象发送方,事件参数e)
{
var originalChars=txtbaynumber.Text.ToCharArray();
List odddights=新列表();
列表=新列表();
int oddTotal=0,evenTotal=0,total=0,checkDigit;
常数int=3;
常数int模=10;
bool-isOdd=真;
对于(int x=0;x
我还没有完成测试,一旦BPAY回复我,我会发回


编辑:试试这个:

这个PHP函数将根据mod10版本5算法生成BPay参考号

谁知道为什么BPay不能将此添加到他们的网站。我只是通过谷歌搜索找到了一个解释,发现算法被称为“MOD10V05”,而不是“mod10version5”

函数generateBayRef($number){
$number=preg_replace(“/\D/”、“”、$number);
//种子编号必须是数字
如果(!is_numeric($number))返回false;
//必须是正数

如果($number,这里有一种在sql server中使用t-sql用户定义函数实现“MOD10V5”算法(或“mod 10 version 5”)的方法。它接受最长9个字符的客户ID,并返回11个字符的CRN(客户参考号)

我还在CustomerID的开头预先添加了一个版本号,如果您认为将来可能会更改它,您也可以这样做

CREATE Function [dbo].[CalculateBPayCRN]
(
    @CustomerID nvarchar(9)
)
RETURNS varchar(11)
AS
BEGIN

    DECLARE @NewCRN nvarchar(11)
    DECLARE @Multiplier TINYINT 
    DECLARE @Sum int
    DECLARE @SubTotal int  
    DECLARE @CheckDigit int  
    DECLARE @ReturnVal BIGINT

    SELECT @Multiplier = 1
    SELECT @SubTotal = 0

    -- If it's less than 9 characters, pad it with 0's, then prepend a '1'

    SELECT  @NewCRN = '1' + right('000000000'+ rtrim(@CustomerID), 9)

    -- loop through each digit in the @NewCRN, multiple it by the correct weighting and subtotal it:

    WHILE @Multiplier <= LEN(@NewCRN)  
    BEGIN  

        SET @Sum =  CAST(SUBSTRING(@NewCRN,@Multiplier,1) AS TINYINT) * @Multiplier  
        SET @SubTotal = @SubTotal + @Sum  
        SET @Multiplier = @Multiplier + 1  

    END 

    -- mod 10 the subtotal and the result is our check digit

    SET @CheckDigit = @SubTotal % 10  

    SELECT @ReturnVal = @NewCRN + cast(@CheckDigit as varchar)

    RETURN @ReturnVal
END
GO
创建函数[dbo]。[CalculatedBayCRN]
(
@客户ID nvarchar(9)
)
返回varchar(11)
作为
开始
声明@NewCRN nvarchar(11)
声明@Multiplier TINYINT
声明@Sum int
声明@SubTotal int
声明@CheckDigit int
声明@ReturnVal-BIGINT
选择@Multiplier=1
选择@SubTotal=0
--如果少于9个字符,请用0填充,然后在“1”前面加上前缀
选择@NewCRN='1'+右('000000000'+rtrim(@CustomerID),9)
--循环遍历@NewCRN中的每个数字,将其乘以正确的权重并小计:

而PHP中的@MultiplierModula 10 V1。针对我的Windows dataflex例程进行了测试,结果是一样的

function generateBpayRef($number) {
    //Mod 10 v1
    $number = preg_replace("/\D/", "", $number);

    // The seed number needs to be numeric
    if(!is_numeric($number)) return false;
    // Must be a positive number
    if($number <= 0) return false;

    $stringMemberNo =  "$number";
    $stringMemberNo = str_pad($stringMemberNo, 6, "0", STR_PAD_LEFT);  
    //echo " Padded Number is $stringMemberNo  ";
    $crn = $stringMemberNo;

    for($i=0;$i<7;$i++){
           $crnval = substr($crn,(5-$i),1);
           $iPartVal = $iWeight * $crnval;

           if($iPartVal>9){
             //echo " Greater than 9: $iPartVal ";
             $firstChar = substr($iPartVal,0,1); 
             $secondChar = substr($iPartVal,1,1);                           
             $iPartVal=$firstChar+$secondChar;
             //$iPartVal -= 9;

           }
           $iSum+=$iPartVal;

           $iWeight++;
           if ($iWeight>2){$iWeight=1;}

           //echo " CRN: $crnval ] Weight: $iWeight ] Part: $iPartVal ] SUM: $iSum ";
    }
    $iSum %= 10;

    if($iSum==0){
        //echo " zero check  is $iSum ";                    
        //return $iSum;
    }
    else{
        //return 10-$iSum;
        $iSum=(10-$iSum);
    }
    //echo " Check is a $iSum ";                                        

    $BpayMemberNo  = $stringMemberNo . $iSum ;
    echo " New: $BpayMemberNo ";
    return ($BpayMemberNo);
}
函数generateBayRef($number){
//Mod 10 v1
$number=preg_replace(“/\D/”、“”、$number);
//种子编号必须是数字
如果(!is_numeric($number))返回false;
//必须是正数
如果($number 2){$iWeight=1;}
//echo“CRN:$crnval]重量:$iWeight]部件:$iPartVal]总和:$iSum”;
}
$iSum%=10;
如果($iSum==0){
//echo“零检查为$iSum”;
//返回$iSum;
}
否则{
//返回10-$iSum;
$iSum=(10-$iSum);
}
//echo“支票是$iSum”;
$BpayMemberNo=$stringMemberNo.$iSum;
echo“新:$BpayMemberNo”;
返回($BpayMemberNo);
}

我必须为javascript制定一个版本,这就是我想到的。它正确地生成了原始问题中预期的数字

var startingNumber = 2005;
var reference = startingNumber.toString();
var subTotal = 0;
for (var x = 0; x < reference.length; x++) {
    subTotal += (x + 1) * reference.charAt(x);
}
var digit = subTotal % 10;
var bpayReference = reference + digit.toString();
var startingNumber=2005;
var reference=startingNumber.toString();
var小计=0;
对于(var x=0;x
这是我使用vb.net创建的一个函数,用于计算mod 10版本5的校验位

Private Function CalcCheckDigit(ByRef psBaseNumber As String) As String

    Dim lCheckDigit, iLoop As Integer
    Dim dCalcNumber As Double

    lCheckDigit = 0
    dCalcNumber = 0

    For iLoop = 0 To (psBaseNumber.Length - 1)

        lCheckDigit = lCheckDigit + (psBaseNumber.Substring(iLoop, 1) * (iLoop + 1))

    Next iLoop

    lCheckDigit = lCheckDigit Mod 10
    CalcCheckDigit = psBaseNumber & CStr(lCheckDigit)

End Function

这是一个ruby类,我很快为Mod 10 v5创建了这个类

module Bpay
  class CRN

    attr_accessor :number, :crn

    class << self

      def calculate_for(number)
        new(number).crn
      end

    end

    def initialize(number)
      @number = number
      calculate
    end

    def calculate
      raise ArgumentError, "The number '#{number}' is not valid" unless valid?

      digits      = number.to_s.scan(/\d/).map { |x| x.to_i }
      raise ArgumentError, "The number '#{number}' must be at least 2 digits in length" if digits.size < 2

      check_digit = digits.each_with_index.map { |d, i| d * (i + 1) }.inject(:+) % 10

      @crn = "#{number}#{check_digit}"
    end

    def valid?
      return false unless !!Integer(number.to_s) rescue false
      return false if number.to_i <= 0
      true
    end

  end
end
模块Bpay
类CRN
属性存取器:编号,:crn

全班同学都尽量不要吝啬,你用谷歌搜索过了吗?问题在哪里?你检查过BPAY API并试图向他们提供你的客户ID算法吗?是的,我们知道我们使用的是正确的Luhn,但只是我们的数学有点错。如果BPAY有API,他们应该向你提供校验和。我会努力让他们o确认你的工作。在此期间,也许Math SE网站会对此感到高兴?谢谢,我已经在那里发布了它。@Dermot那么,使用该PDF,我该如何做我的数学?谢谢,我今晚会仔细看一看。我个人不懂C,但我理解私有空间(对我来说,它=函数)我不知道为什么他们也不能。现在我只希望银行在sameone付款时通知我bpay@RussellHarrower如果您指的是实时通知,那么使用BPAY从根本上说是很困难的,因为付款人可能在不同的银行,而且银行每晚只交换批处理文件。@nick adams是否有源代码参考或MOD10V05?我发现与您相同,但没有看到权威来源(例如ISO标准或类似标准)。对你并不挑剔,但似乎这个空间在网上没有很好的文档记录?请注意:BPay CRN实际上不是整数,它们是字符串,因为它们可以让前导0和前导0完全改变MOD10v05校验和数字。谢天谢地,修改这个t-sql来解释前导0是很容易的。uuh你知道什么t?我在错误的答案上留下了这个评论。我道歉!哈,是的,它发生了:)你可以删除你的评论。
Private Function CalcCheckDigit(ByRef psBaseNumber As String) As String

    Dim lCheckDigit, iLoop As Integer
    Dim dCalcNumber As Double

    lCheckDigit = 0
    dCalcNumber = 0

    For iLoop = 0 To (psBaseNumber.Length - 1)

        lCheckDigit = lCheckDigit + (psBaseNumber.Substring(iLoop, 1) * (iLoop + 1))

    Next iLoop

    lCheckDigit = lCheckDigit Mod 10
    CalcCheckDigit = psBaseNumber & CStr(lCheckDigit)

End Function
module Bpay
  class CRN

    attr_accessor :number, :crn

    class << self

      def calculate_for(number)
        new(number).crn
      end

    end

    def initialize(number)
      @number = number
      calculate
    end

    def calculate
      raise ArgumentError, "The number '#{number}' is not valid" unless valid?

      digits      = number.to_s.scan(/\d/).map { |x| x.to_i }
      raise ArgumentError, "The number '#{number}' must be at least 2 digits in length" if digits.size < 2

      check_digit = digits.each_with_index.map { |d, i| d * (i + 1) }.inject(:+) % 10

      @crn = "#{number}#{check_digit}"
    end

    def valid?
      return false unless !!Integer(number.to_s) rescue false
      return false if number.to_i <= 0
      true
    end

  end
end