如何在C#中生成CUSIP校验位

时间:2014-03-06 17:08:55

标签: c# algorithm financial check-digit

CUSIP是一个9位数的字母数字代码,用于唯一标识财务安全性。

https://en.wikipedia.org/wiki/CUSIP

它们是在1964年发明的,并且考虑到60年代数据传输的可靠性,第9位实际上是用于确认前8个字符有效性的校验位。有时候,即使在今天,你也可能有理由想要验证CUSIP,或者公司或服务公司或服务公司决定只传输8个字符的CUSIP,即使这会破坏校验位的目的。

生成校验位的过程是:

  1. 根据字母表中的序号位置加上9(A = 10,B = 11,... Z = 35)将非数字数字转换为值并转换字符* = 36,@ = 37 ,#= 38。

  2. 将每个偶数乘以2

  3. 如果乘法的结果是两位数,请将数字相加。 (12 = 1 + 2 = 3)

  4. 获取所有值的总和。

  5. 获取此操作的内含值:(10 - ( sum 模10))模10。

  6. 在C#中获取此值的最佳/最简单方法是什么?

2 个答案:

答案 0 :(得分:10)

自我回答,因为我昨天正在谷歌上搜索,并想在某个时间将某人赶出去。我确实希望听到更多的答案或反馈。

public string GenerateCheckDigit(string cusip)
{        
    int sum = 0;
    char[] digits = cusip.ToUpper().ToCharArray();
    string alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ*@#";

    for (int i = 0; i < digits.Length; i++)
    {
        int val;
        if (!int.TryParse(digits[i].ToString(), out val))
            val = alphabet.IndexOf(digits[i]) + 10;

        if ((i % 2) != 0)
            val *= 2;

        val = (val % 10) + (val / 10);

        sum += val;
    }

    int check = (10 - (sum % 10)) % 10;

    return check.ToString();
}

编辑:

.NET小提琴演示:https://dotnetfiddle.net/kspQWl

答案 1 :(得分:3)

如果预先计算校验位的值,并将它们存储在查找表中,那么校验位的计算将变得更加简单:

private static readonly int[,] Check = new int[128, 2];

static CusipCheckSum() {
    var cusipChars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ*@#";
    for (var i = 0 ; i != cusipChars.Length ; i++) {
        Check[cusipChars[i], 0] = i%10 + i/10;
        Check[cusipChars[i], 1] = 2*i%10 + 2*i/10;
    }
}

使用2D查找数组,您可以在一行代码中计算校验位:

var checkDigit = (10-(cusip.Select((ch, pos) => Check[ch, pos%2]).Sum()%10))%10;