銀行卡卡號檢測Luhn算法 Objective-C實現
Luhn 算法簡介
Luhn 算法或是Luhn 公式,也被稱作“模10算法”。它是一種簡單的校驗公式,一般會被用於身份證號碼,IMEI號碼,美國供應商識別號碼,或是加拿大的社會保險號碼的驗證。該算法是由IBM的科學家Hans Peter Luhn所創造,於1954年1月6日提出該專利的申請,並於1960年8月23日被授予,在美國的專利號爲2950048。
該算法一直都被大家所公用,並且時至今日應用也很廣泛。它被指定在ISO/IEC7812-1。它的目的不是成爲一種加密安全的哈希函數;它的目的是防止意外出現的錯誤,而不是惡意攻擊。很多信用卡和衆多的政府身份識別號碼都使用該算法從一系列的隨機數字中提取有效的數字。
優點和缺點
Luhn 算法會檢測到任何單碼的錯誤以及幾乎所有的相鄰數字換位的錯誤。但是它不會檢測兩個數字序列09轉90的錯誤(反之亦然)。它會檢測到十分之七的相同雙位數錯誤(不會檢測到22和55的互換,33和66的互換,44和77的互換)。其他更復雜的檢查數字算法,如費爾赫夫算法,可以檢測出更多的轉錄錯誤。模N的Luhn算法是Luhn算法的一個擴展,支持非數字字符串。因爲該算法採取了從右向左的方式,而且零位會影響計算的結果。只有當零位造成了數位的移動或是用零來填充一串數字的開頭時纔不會影響計算結果的生成。因此不論在將1234用零填充爲0001234之前或是之後,使用Luhn算法得到的結果都是一樣的。
該算法在美國專利上是爲了給手持或是機械設備計算校驗碼。所以它必須儘可能的簡單。
算法描述
- 從卡號最後一位數字開始,偶數位乘以2,如果乘以2的結果是兩位數,將結果個位和十位相加,或者直接減去9。
- 把所有數字相加,得到總和。
- 如果信用卡號碼是合法的,總和可以被10整除。
OC實現
/**
* 匹配Luhn算法:可用於檢測銀行卡卡號
* @param cardNo
* @return
*/
+(BOOL)isMatchLuhn:(NSString*)cardNo {
cardNo = [cardNo stringByReplacingOccurrencesOfString:@" " withString:@""];
/* 步驟1
按照從右往左的順序,從這串數字的右邊開始,包含校驗碼,將偶數位數字乘以2,
如果每次乘二操作的結果大於9(如 8 × 2 = 16),然後計算個位和十位數字的和
(如 1 + 6 = 7)或者用這個結果減去9(如 16 - 9 = 7) */
NSMutableArray* newNumArray = [NSMutableArray array];
NSString* cardNoChar = nil;
for(long i = cardNo.length - 2; i >= 0; i -= 2)
{
// 奇數位
cardNoChar = [cardNo substringWithRange:NSMakeRange(i + 1, 1)];
[newNumArray addObject:cardNoChar];
// 偶數位
cardNoChar = [cardNo substringWithRange:NSMakeRange(i, 1)];
int k = [cardNoChar intValue]*2;
// 處理大於9的情況
k = k % 10 + k / 10;
[newNumArray addObject:[NSString stringWithFormat:@"%d", k]];
if (i == 1) {
// 奇數位
cardNoChar = [cardNo substringWithRange:NSMakeRange(i - 1, 1)];
[newNumArray addObject:cardNoChar];
}
}
/* 步驟2 第一步操作過後會得到新的一串數字,計算所有數字的和(包含校驗碼) */
int sum = [[newNumArray valueForKeyPath:@"@sum.integerValue"] intValue];
/* 步驟3 用第二步操作得到的和進行“模10”運算,如果結果位0,表示校驗通過,否則失敗 */
return sum % 10 == 0;
}