嗨,我知道这里可能有人对此提出疑问,但我无法找到一个足够详细的答案,维基百科有两个ISIN的例子,以及它们的校验和是如何计算的。
我一直在努力计算的那一部分是
乘包含最右边字符的组
我对这一说法的理解是:
even数,则为even位置中的所有数值加倍。odd数,则为odd位置中的所有数值加倍。
我的理解肯定是错误的,因为至少有两个问题:
备注
isin.org包含的验证ISIN的信息甚至更少,他们甚至使用与维基百科相同的例子。
发布于 2018-02-28 11:09:23
我同意你的观点,维基百科的定义并不是我所见过的最清晰的。
在这两个示例前面有一段文字,说明何时应该使用其中一种算法:
由于NSIN元素可以是任何alpha数字序列(9个字符),奇数的字母将导致偶数的数字,而偶数的字母将导致奇数的数字。对于奇数位数,使用第一个示例中的方法。对于偶数位数,使用第二个示例中的方法。
NSIN与ISIN相同,不包括前两个字母和最后一个数字;因此,如果ISIN是US0378331005,则NSIN是037833100。因此,如果要验证US0378331005的校验和数字,就必须使用“第一个算法”,因为NSIN中有9位数字。相反,如果您想检查AU0000XVGZA3,您将使用“第二个算法”,因为NSIN包含4位数字。
至于“第一”和“第二”算法,它们是相同的,唯一的例外是,在前者中,奇数组将乘以2,而在后一组中,将偶数组乘以2。
现在,好消息是,没有这个过于复杂的算法,你可以逃脱。
相反,你可以:
唯一棘手的步骤是#4,让我们用一个小例子来澄清它。假设奇数位置上的数字是4, 0, 7。
你会把它们加倍,得到:8, 0, 14。
8不是>= 10,所以我们认为它是。我也是。14是>= 10,所以我们再加一次它的数字:1+4=5。
因此,这个迷你示例中第4步的结果是:8, 0, 5。
Python中的一个最低限度的工作实现可能如下所示:
import string
isin = 'US4581401001'
def digit_sum(n):
return (n // 10) + (n % 10)
alphabet = {letter: value for (value, letter) in
enumerate(''.join(str(n) for n in range(10)) + string.ascii_uppercase)}
isin_to_digits = ''.join(str(d) for d in (alphabet[v] for v in isin[:-1]))
isin_sum = 0
for (i, c) in enumerate(reversed(isin_to_digits), 1):
if i % 2 == 1:
isin_sum += digit_sum(2*int(c))
else:
isin_sum += int(c)
checksum_digit = abs(- isin_sum % 10)
assert int(isin[-1]) == checksum_digit或者,更多的是为了功能性的乐趣:
checksum_digit = abs( - sum(digit_sum(2*int(c)) if i % 2 == 1 else int(c)
for (i, c) in enumerate(
reversed(''.join(str(d) for d in (alphabet[v] for v in isin[:-1]))), 1)) % 10)https://stackoverflow.com/questions/46061228
复制相似问题