首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >计算ISIN校验和

计算ISIN校验和
EN

Stack Overflow用户
提问于 2017-09-05 18:27:31
回答 1查看 2.3K关注 0票数 3

嗨,我知道这里可能有人对此提出疑问,但我无法找到一个足够详细的答案,维基百科有两个ISIN的例子,以及它们的校验和是如何计算的。

我一直在努力计算的那一部分是

乘包含最右边字符的组

我对这一说法的理解是:

  • 从右到左遍历每个字符
  • 一旦你偶然发现一个字符,而不是数字,记录它的位置
    • 如果该位置为even数,则为even位置中的所有数值加倍。
    • 如果该位置为odd数,则为odd位置中的所有数值加倍。

我的理解肯定是错误的,因为至少有两个问题:

  • 每个ISIN都以两个字符的国家代码开头,因此最右边字符的位置总是第一个字符。
  • 如果省略前两个字符,则无法解释如何处理由所有数字组成的ISIN(前两个字符除外)。

备注

isin.org包含的验证ISIN的信息甚至更少,他们甚至使用与维基百科相同的例子。

EN

回答 1

Stack Overflow用户

发布于 2018-02-28 11:09:23

我同意你的观点,维基百科的定义并不是我所见过的最清晰的。

在这两个示例前面有一段文字,说明何时应该使用其中一种算法:

由于NSIN元素可以是任何alpha数字序列(9个字符),奇数的字母将导致偶数的数字,而偶数的字母将导致奇数的数字。对于奇数位数,使用第一个示例中的方法。对于偶数位数,使用第二个示例中的方法。

NSIN与ISIN相同,不包括前两个字母和最后一个数字;因此,如果ISIN是US0378331005,则NSIN是037833100。因此,如果要验证US0378331005的校验和数字,就必须使用“第一个算法”,因为NSIN中有9位数字。相反,如果您想检查AU0000XVGZA3,您将使用“第二个算法”,因为NSIN包含4位数字。

至于“第一”和“第二”算法,它们是相同的,唯一的例外是,在前者中,奇数组将乘以2,而在后一组中,将偶数组乘以2。

现在,好消息是,没有这个过于复杂的算法,你可以逃脱。

相反,你可以:

  1. 取ISIN,除了最后一个数字(您需要验证该数字)。
  2. 将所有字母转换为数字,以便获得数字列表
  3. 反转数字列表
  4. 如果结果是>= 10,则奇数位置上的所有数字都加倍,并且它们的数字再次相加。
  5. 偶数位置上的所有数字都按原样取下来。
  6. 所有数字之和,取模,从0减去结果,取绝对值。

唯一棘手的步骤是#4,让我们用一个小例子来澄清它。假设奇数位置上的数字是4, 0, 7

你会把它们加倍,得到:8, 0, 14

8不是>= 10,所以我们认为它是。我也是。14是>= 10,所以我们再加一次它的数字:1+4=5

因此,这个迷你示例中第4步的结果是:8, 0, 5

Python中的一个最低限度的工作实现可能如下所示:

代码语言:javascript
复制
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

或者,更多的是为了功能性的乐趣:

代码语言:javascript
复制
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)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46061228

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档