AEMO Checksum Ruby代码

时间:2017-02-23 01:58:04

标签: javascript ruby excel vba luhn

我无法编写Ruby代码,但是我找到了这个ruby代码来计算AEMO NMI的校验和

def checksum
  summation = 0
  @nmi.reverse.split(//).each_index do |i|
    value = nmi[nmi.length - i - 1].ord
    value *= 2 if i.even?
    value = value.to_s.split(//).map(&:to_i).reduce(:+)
    summation += value
  end
  checksum = (10 - (summation % 10)) % 10
  checksum
end

有人可以帮我解释一下这行是什么意思吗?

value = value.to_s.split(//).map(&:to_i).reduce(:+)

我尝试将上面的代码转换为VBA for excel。

输入" 4103738516"会给你8 " 4102030716" ==> 2 " QFFF0000LV" ==> 7

本文档第40页的

包含用于计算的JavaScript代码,但我无法理解代码。

https://www.aemo.com.au/-/media/Files/PDF/0610-0008-pdf.pdf

谢谢

2 个答案:

答案 0 :(得分:1)

下面的代码可以让你更好地理解这句话:

# Say
value = 82478923    # any random number
value.to_s          # => "82478923"

# `split(//)` is similar to `split` and `split('')`, they split a string after each character to generate an array of characters.
ary = value.to_s.split(//)      # => ["8", "2", "4", "7", "8", "9", "2", "3"]

ary.map(&:to_i)     # => [8, 2, 4, 7, 8, 9, 2, 3]

# `inject(:+)` will iterate the array and calculate sum of all numbers
ary.map(&:to_i).inject(:+)      # => 43

在此处详细了解inject

答案 1 :(得分:0)

如果有人需要,我会将这个Ruby代码翻译成VBA。

用法:Calc_Checksum(NMI)

Function StrReverse(strInput As String) As String

    Dim strRev As String
    Dim i As Integer
    Dim length As Integer


    strRev = ""
    length = Len(strInput)

    For i = 0 To length - 1
        strRev = strRev & Mid(strInput, length - i, 1)
    Next i

    StrReverse = strRev

End Function

Function Calc_Checksum(strNMI As String)

    Dim i As Integer
    Dim j As Integer
    Dim x As Integer
    Dim chrV As Integer
    Dim tmpStr As String

    Dim s As Integer

    s = 0
    ' Reverse strNMI
    strNMI = StrReverse(strNMI)


    'Loop through each char
    For i = 0 To Len(strNMI) - 1


        chrV = Asc(Mid(strNMI, i + 1, 1))
        'debug.Print chrV

        If i Mod 2 = 0 Then
            chrV = chrV * 2
        End If

        tmpStr = CStr(chrV)
        v = 0
        For j = 1 To Len(tmpStr)

            v = v + CInt(Mid(tmpStr, j, 1))

        Next j

        s = s + v

    Next i


    Calc_Checksum = (10 - (s Mod 10)) Mod 10

End Function