OCL中如何实现Luhn算法

How to implement the Luhn alorithm in OCL

我正在尝试在 OCL 中找到 Luhn 算法来检查 ISIN 的有效性。谁能提供一个代码示例就太好了!

创建 class:

   Attribute NextMult1Or2:Integer
   Method MultWith2Or1SumBiggerThan10(v:Integer):Integer
   Method GetCheckSum(input:String):Integer

第一个方法MultWith2Or1SumBiggerThan10:

let res=v*self.NextMult1Or2 in
(
  if self.NextMult1Or2=2 then
    self.NextMult1Or2:=1
  else
    self.NextMult1Or2:=2
  endif;
 if res>10 then
  res-9
 else
  res
 endif 
)

和第二种方法GetCheckSum(input:String):Integer

self.NextMult1Or2:=2;
input.ToCharArray->collect(c|
  let i=Integer.Parse(c) in (
    self.MultWith2Or1SumBiggerThan10(i)  
  )
)->sum

要计算校验和 - 将校验位以外的所有内容发送到 GetCheckSum - 校验位是 (((res+10) / 10).Truncate*10)-res(即与上面最近的 10:th 的差异)

要检查序列,请将包括校验位在内的所有内容发送到 GetCheckSum - 如果 res.Mod(10)= 0 它已通过

在纯 OCL 中使用 https://en.wikipedia.org/wiki/Luhn_algorithm

中的示例
let s = Sequence{7,9,9,2,7,3,9,8,7,1} in
(Sequence{1..s->size()}
    ->collect(i | 
        let t = s->at(i) in
        if i.mod(2) = 1
        then t
        else let tt = 2 * t in tt.div(10) + tt.mod(10)
        endif)
    ->sum()*9)
.mod(10)

在有关 Luhns 算法的德语维基百科文章 (https://de.wikipedia.org/wiki/Luhn-Algorithmus) 中,您可以找到一个示例来计算 446-667-651 标识的值。下面的算法计算出正确的值 40。

let list = '446667651'.ToCharArray.strToInt in 
Sequence{1..list->size}
->Collect(i|
    if (list->size-i).Mod(2)=0 then 
        list.at(i) 
    else 
        (list.at(i)*2).Mod(9) 
    endif)
->Sum

也许您需要一些调整来计算 ISIN 的值。