ISBN、一个18位身份证和计算信用卡(Luhns)的算法

一、ISBNCheckDigit()不仅可以确保在管理图书库应用程序中输入有效的ISBN;还可以用于让浏览者输入ISBN进行查询的Web程序。其算法的原理如下:

一个ISBN编号包含10个数字,其中最后一个是校验位。计算校验位时,要把前9位数字乘以常数;第1位乘以10,第2位乘以9,以此类推。当结果为10时,检验位以“X”表示。举例来说,为了计算ISBN078212283的校验位,先要计算如下所示的和:0*10+7*9+8*8+2*7+1*6+2*5+2*4+8*3+3*2=195,195除以11,余8,因此校验码为11-8=3。那么这本书完整的ISBN为0782122833。其自定义的ISBNCheckDigit()函数为:

    Function ISBNCheckDigit(ByVal ISBN As String) As String
        Dim i As Integer, chksum, chkDigit As Integer
        For i = 0 To 8
            chksum = chksum + (10 - i) * Convert.ToInt16(ISBN.Substring(i, 1))
        Next
        chkDigit = 11 - (chksum Mod 11)
        If chkDigit = 10 Then
            Return ("X")
        ElseIf chkDigit = 11 Then
            Return ("0")
        Else
            Return (chkDigit.ToString)
        End If
    End Function

二、一个18位身份证校验计算函数

关于身份证第18是怎么计算的,原理如下

根据〖中华人民共和国国家标准 GB 11643-1999〗中有关公民身份号码的规定,公民身份号码是特征组合码,由十七位数字本体码和一位数字校验码组成。排列顺序从左至右依次为:六位数字地址码,八位数字出生日期码,三位数字顺序码和一位数字校验码。

地址码表示编码对象常住户口所在县(市、旗、区)的行政区划代码。生日期码表示编码对象出生的年、月、日,其中年份用四位数字表示,年、月、日之间不用分隔符。顺序码表示同一地址码所标识的区域范围内,对同年、月、日出生的人员编定的顺序号。顺序码的奇数分给男性,偶数分给女性。校验码是根据前面十七位数字码,按照ISO 7064:1983.MOD 11-2校验码计算出来的检验码。下面举例说明该计算方法。

15位的身份证编码首先把出生年扩展为4位,简单的就是增加一个19,但是这对于1900年出生的人不使用(这样的寿星不多了)

某男性公民身份号码本体码为34052419800101001,首先按照公式⑴计算:

∑(ai×Wi)(mod 11)……………………………………(1)

公式(1)中:
i----表示号码字符从由至左包括校验码在内的位置序号;
ai----表示第i位置上的号码字符值;
Wi----示第i位置上的加权因子,其数值依据公式Wi=2(n-1)(mod 11)计算得出。

i 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1

ai 3 4 0 5 2 4 1 9 8 0 0 1 0 1 0 0 1 a1

Wi 7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2 1

ai×Wi 21 36 0 25 16 16 2 9 48 0 0 9 0 5 0 0 2 a1

根据公式(1)进行计算:

∑(ai×Wi) =(21+36+0+25+16+16+2+9+48++0+0+9+0+5+0+0+2) = 189

189 ÷ 11 = 17 + 2/11

∑(ai×Wi)(mod 11) = 2

然后根据计算的结果,从下面的表中查出相应的校验码,其中X表示计算结果为10:

∑(ai×WI)(mod 11) 0 1 2 3 4 5 6 7 8 9 10
校验码字符值ai         1 0 X 9 8 7 6 5 4 3  2
根据上表,查出计算结果为2的校验码为所以该人员的公民身份号码应该为 34052419800101001X。

a[0]*7+a[1]*9+a[2]*10+a[3]*5+a[4]*8+a[5]*4+a[6]*2+a[7]*1+a[8]*6+a[9]*3
+a[10]*7+a[11]*9+a[12]*10+a[13]*5+a[14]*8+a[15]*4+a[16]*2
%11

因需要对15位旧身份证号码进行升位和校验、查询处理,又没有搜索到现成的函数,于是自己写了一个简单的过程,希望能够帮得上需要的朋友。
本函数的功能单一,只能校验第18位号码是否正确或者取得第18位号码,其他功能留给大家自己扩展吧!

<%
'' Version: 1.0.1
'' Author: sfply(sfply@163.com)
'' Last Modified: 2004/7/17 12:03
'' Src是身份证号码,可以是15位也可以是18位,15位时只能返回验证码方式使用
'' iChk参数取值真假,真代表校验Src是否18位身份证,并且校验第18位是否正确号码而确定是否有效身份证,返回只值为true或false
'' 假代表返回正确的校验码,返回值为(1~x)
dim myIdentify
myIdentify = 36050219781218133?

response.write chkIdentiyCard(myIdentify,false)

Function chkIdentiyCard(Src,iChk)
dim myWi,myAi,mySrc(17),i,myCount
myAi = 10X98765432
myWi = split(7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2,,)
if iChk then
if len(Src) = 18 then
for i = 0 to 16
mySrc(i) = mid(Src,i+1,1)
myCount = myCount + mySrc(i) * myWi(i)
next
if mid(myAi,(mycount mod 11)+1,1) = right(Src,1) then
chkIdentiyCard = true ''返回结果,TRUE为合法身份证验证码
else
chkIdentiyCard = false ''返回结果,FALSE为非法身份证验证码
end if
else
chkIdentiyCard = false ''因为不是18位身份证所以返回FALSE
end if
else
if len(Src) = 15 or len(Src) = 18 then
if len(Src) = 15 then Src = mid(Src,1,6) & 19 & mid(Src,7,9)
for i = 0 to 16
mySrc(i) = mid(Src,i+1,1)
myCount = myCount + mySrc(i) * myWi(i)
next
chkIdentiyCard = mid (myAi,(mycount mod 11)+1,1) ''返回正确的验证码
else
chkIdentiyCard = false ''输入不不是15位或18位身份证号
end if
end if
End Function
%>

三、计算信用卡的校验码的算法

支付卡校验位算法,记录一下算法:

1. 对卡号上的每位数字乘以权重。其规则是,如果卡号数字个数是偶数,则第一位乘以2,否则就乘以1,然后以后分别是,1,2,1,2,1,2;
2. 如果每位数字乘以权重后超过9 ,则需要减去 9;
3. 将所有的处理过的加权数字求和,用 数字 10 求模运算;
4. 余数应该是0,否则可能是输入错误。也可能是一个假号。

The Luhn Mod-10 Method (ISO 2894/ANSI 4.13) involves a check digit in the
one's position.  The check digit is calculated starting at the right with
the digit immediately preceding the check digit (ten's digit) and moving
toward the left, doubling every other digit.  If a doubled digit is greater
than nine, the two digits are added to together to obtain a single-digit
result.  The sum of all the resulting digits (including those skipped) is then
taken modulo with 10, to obtain the check digit.

Below, is untested code.

/************************************************************************
*  LuhnMod10 - self-checking scheme for validating card account numbers
*  according to ISO 2894/ANSI 4.13.
*
*    Ex:  cardNumber = "795102879015546"
*         strlen(cardNumber) == 15
*         LuhnMod10(cardNumber, 14) == 6 == cardNumber[14]
*
************************************************************************/
int LuhnMod10(char* cardNumber, int size)
{
  static int table[2][10] = { {0,1,2,3,4,5,6,7,8,9}, {0,2,4,6,8,1,3,5,7,9} };

  for (int i=size-1, odd=0, sum=0; i>=0; i--)
    if (isdigit(cardNumber[i]))
      sum += table[(odd=1-odd)][cardNumber[i]-'0'];
  sum %= 10;
  return (sum ? 10-sum : 0);               /* return the check digit */


有的网友可能会动起脑筋,那么是否可以伪造一个信用卡号码呢,嘿嘿嘿,不要忘了还有用户卡上的名字和三位验证码呢, 重要的是,书中告诉我们: 盗用信用卡号码是犯罪行为

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值