作为针对第三方服务的集成的一部分,我需要计算一个校验位。我已经获得了一个PHP片段来显示算法,但我需要在pl / sql中实现它。 PHP代码段(取自here)是:
function arvutaViitenumber($nr){
$nr = (string)$nr;
$kaal = array(7,3,1);
$sl = $st = strlen($nr);
$total = 0;
while($sl > 0 and substr($nr, --$sl, 1) >='0'){
$total += substr($nr, ($st-1)-$sl, 1)*$kaal[($sl%3)];
}
$kontrollnr = ((ceil(($total/10))*10)-$total);
return $nr.$kontrollnr;
}
除了循环中的substr($nr, --$sl, 1) >='0'
条件外,我理解其中的大部分内容。我有两件事情我不明白:
循环的主体从头开始按顺序取每个数字。那么为什么在根据末尾第n个数字的状态从开始处理第n个数字之前出现循环退出的条件?
将单字符字符串比较为大于或等于字符串'0'
时,条件是否为假?在我的测试中,它总是正确的,即使比较的字符串是一个字符而不是一个数字。
问题1更多的是学术上的兴趣。我真正感兴趣的是问题2以及我将如何在pl / sql版本中实现此检查(或者我是否需要?)
答案 0 :(得分:2)
1。好吧,想想相反的情况。
$st = strlen($nr);
$sl = $total = 0;
while($sl < strlen($nr) and substr($nr, ++$sl, 1) >='0'){
注意while循环中的strlen
- 不好的做法。虽然在PHP中速度很快,但在大多数编程语言中,这对性能来说太糟糕了。另一种选择是使用另一个变量,它将是还原剂。
因此,懒惰和表现的最佳选择是从最后开始。
2. 据我所知,字符串比较的唯一目的是确保ASCII表中的位置高于或等于'0'
ASCII否。 48)。首先,检查http://www.asciitable.com/
然后看看我做的以下测试:
var_dump(' ' >= '0'); // false // space has ASCII no 32
var_dump('(' >= '0'); // false // ASCII no 47
var_dump('A' >= '0'); // true // ASCII no 65
var_dump('[' >= '0'); // true // ASCII no 71
正如@mudasobwa所提到的那样,它几乎是一个字母数字测试。
答案 1 :(得分:1)
1。你不应该试图在算法中找到任何逻辑:它是有点散列函数,它的目标是在相同的输入上给出相同的“验证”值。例如,看看Java的String::hashCode()
实现。
2。他们决定带来额外的熵,当结尾的第n个不是字母数字时停止循环。而已。没有隐藏的感觉。
答案 2 :(得分:0)
如果将单字符串比较为大于或等于字符串时 &#39; 0&#39;这种情况可能是假的吗?在我的测试中,它总是如此, 即使比较的字符串是字符而不是数字。
"<string>" >= '0'
为空或空或负数,则 <string>
为false,但如果为0或&#39; 0&#39;则为真或其他
不要被这里的类型所迷惑,>=
将(与>==
相反)默认为/ cast到某种类型。 (因为它的php,它不可能记住哪个,至少对我而言)
编辑:false >= '0'
也是如此 - 这可能就在这里