Luhn mod N algoritmi - Luhn mod N algorithm

The Luhn mod N algoritmi ning kengaytmasi Luhn algoritmi (shuningdek, mod 10 algoritmi deb ham ataladi), bu istalgan qiymatlar ketma-ketligi bilan ishlashga imkon beradi tayanch. Bu harflar, harflar va raqamlar birikmasi yoki har qanday o'zboshimchalik bilan N belgilar to'plamidan tashkil topgan identifikator satrini tasdiqlash uchun tasdiq raqami zarur bo'lganda foydali bo'lishi mumkin.

Norasmiy tushuntirish

Luhn mod N algoritmi kirish satri bilan bir xil haqiqiy belgilar oralig'ida tekshiruv raqamini (aniqrog'i, tasdiqlash belgisini) hosil qiladi. Masalan, agar algoritm kichik harflar qatoriga qo'llanilsa (a ga z), belgi ham kichik harf bo'ladi. Ushbu farqdan tashqari, u asl algoritmga juda o'xshash.

Kengaytmaning asosiy g'oyasi shundaki, to'g'ri kiritilgan belgilarning to'liq to'plami kod nuqtalari ro'yxatiga (ya'ni, noldan boshlanadigan ketma-ket butun sonlar) joylashtirilgan. Algoritm kirish satrini har bir belgi bilan bog'langan kod nuqtasiga o'zgartirib, keyin N rejimida hisoblashlarni amalga oshiradi (bu erda N to'g'ri kiritilgan belgilar soni). Nihoyat, natijada olingan tekshiruv kodi mos keladigan belgini olish uchun qaytariladi.

Belgilarni kod nuqtalariga solishtirish

Dastlab, to'g'ri kiritilgan belgilar va kod punktlari o'rtasida xaritalashni yaratish kerak. Masalan, yaroqli belgilar kichik harflardan iborat deb o'ylang a ga f. Shuning uchun tegishli xaritalash quyidagicha bo'ladi:

Belgilarabvdef
Kod-nuqta012345

Belgilar tartibi umuman ahamiyatsiz ekanligini unutmang. Ushbu boshqa xaritalash ham qabul qilinadi (garchi uni amalga oshirish ancha noqulay bo'lsa ham):

Belgilarveafbd
Kod-nuqta012345

Shuningdek, harflar va raqamlarni (va hatto boshqa belgilarni ham) aralashtirish mumkin. Masalan, ushbu xaritalash kichik o'n oltinchi raqamlarga mos keladi:

Belgilar0123456789abvdef
Kod-nuqta0123456789101112131415

C # algoritmi

Quyidagi funktsiyalar belgilanadi:

int CodePointFromCharacter(char belgi) {...}char BelgilarFromCodePoint(int codePoint) {...}int NumberOfValidInputCharacters() {...}

Tekshirish belgisini yaratish funktsiyasi:

char GenerateCheckCharacter(mag'lubiyat kiritish){    int omil = 2;    int sum = 0;    int n = NumberOfValidInputCharacters();    // O'ngdan boshlash va chapga qarab ishlash osonroq     // boshlang'ich "omil" har doim "2" bo'ladi.    uchun (int men = kiritish.Uzunlik - 1; men >= 0; men--)    {        int codePoint = CodePointFromCharacter(kiritish[men]);        int qo'shimchalar = omil * codePoint;        // Har bir "codePoint" ko'paytiriladigan "omil" ni almashtiring        omil = (omil == 2) ? 1 : 2;        // "qo'shish" raqamlarini "n" bazasida ifodalangan holda yig'ing        qo'shimchalar = IntegerValue(qo'shimchalar / n) + (qo'shimchalar % n);        sum += qo'shimchalar;    }    // "yig'indiga" qo'shilishi kerak bo'lgan raqamni hisoblang     // uni "n" ga bo'lish uchun.    int qoldiq = sum % n;    int checkCodePoint = (n - qoldiq) % n;    qaytish BelgilarFromCodePoint(checkCodePoint);}

Va mag'lubiyatni tasdiqlash funktsiyasi (oxirgi belgi sifatida belgi bilan):

bool ValidateCheckCharacter(mag'lubiyat kiritish){    int omil = 1;    int sum = 0;    int n = NumberOfValidInputCharacters();    // O'ngdan boshlab, chapga qarab harakat qiling    // Endi boshlang'ich "omil" har doim "1" bo'ladi     // chunki oxirgi belgi tasdiqlash belgisi.    uchun (int men = kiritish.Uzunlik - 1; men >= 0; men--)    {        int codePoint = CodePointFromCharacter(kiritish[men]);        int qo'shimchalar = omil * codePoint;        // Har bir "codePoint" ko'paytiriladigan "omil" ni almashtiring        omil = (omil == 2) ? 1 : 2;        // "qo'shish" raqamlarini "n" bazasida ifodalangan holda yig'ing        qo'shimchalar = IntegerValue(qo'shimchalar / n) + (qo'shimchalar % n);        sum += qo'shimchalar;    }    int qoldiq = sum % n;    qaytish (qoldiq == 0);}

Java-da algoritm

Quyidagi funktsiyalar belgilanadi:

int codePointFromCharacter(char belgi) {...}char characterFromCodePoint(int codePoint) {...}int numberOfValidInputCharacters() {...}

Tekshirish belgisini yaratish funktsiyasi:

char generateCheckCharacter(Ip kiritish) {    int omil = 2;    int sum = 0;    int n = numberOfValidInputCharacters();    // O'ngdan boshlash va chapga qarab ishlash osonroq    // boshlang'ich "omil" har doim "2" bo'ladi.    uchun (int men = kiritish.uzunlik() - 1; men >= 0; men--) {        int codePoint = codePointFromCharacter(kiritish.charAt(men));        int qo'shimchalar = omil * codePoint;        // Har bir "codePoint" ko'paytiriladigan "omil" ni almashtiring        omil = (omil == 2) ? 1 : 2;        // "Qo'shish" raqamlarini "n" bazasida ifodalangan holda yig'ing        qo'shimchalar = (qo'shimchalar / n) + (qo'shimchalar % n);        sum += qo'shimchalar;    }    // "yig'indiga" qo'shilishi kerak bo'lgan raqamni hisoblang    // uni "n" ga bo'lish uchun.    int qoldiq = sum % n;    int checkCodePoint = (n - qoldiq) % n;    qaytish characterFromCodePoint(checkCodePoint);}

Va mag'lubiyatni tasdiqlash funktsiyasi (oxirgi belgi sifatida belgi bilan):

mantiqiy validateCheckCharacter(Ip kiritish) {    int omil = 1;    int sum = 0;    int n = numberOfValidInputCharacters();    // O'ngdan boshlab, chapga qarab harakat qiling    // Endi boshlang'ich "omil" har doim "1" bo'ladi    // chunki oxirgi belgi tasdiqlash belgisi.    uchun (int men = kiritish.uzunlik() - 1; men >= 0; men--) {        int codePoint = codePointFromCharacter(kiritish.charAt(men));        int qo'shimchalar = omil * codePoint;        // Har bir "codePoint" ko'paytiriladigan "omil" ni almashtiring        omil = (omil == 2) ? 1 : 2;        // "Qo'shish" raqamlarini "n" bazasida ifodalangan holda yig'ing        qo'shimchalar = (qo'shimchalar / n) + (qo'shimchalar % n);        sum += qo'shimchalar;    }    int qoldiq = sum % n;    qaytish (qoldiq == 0);}

Misol

Avlod

Yuqoridagi to'g'ri kiritilgan belgilar to'plamini va misol kiritish satrini ko'rib chiqing abcdef. Tekshirish belgisini yaratish uchun satrdagi oxirgi belgidan boshlang va chapga har ikkala kod-punktni ikki baravar oshiring. Kod-punktlarning 6-bazasida yozilgan "raqamlari" (6 ta kirish belgisi mavjud bo'lganligi sababli) quyidagicha umumlashtirilishi kerak:

Belgilarabvdef
Kod-nuqta012345
Ikki marta26 (10-tayanch)
10 (6-tayanch)
10 (asos 10)
14 (6-tayanch)
Kamaytirish0221 + 041 + 4
Raqamlar yig'indisi022145

Raqamlarning umumiy yig'indisi 14 (0 + 2 + 2 + 1 + 4 + 5). Keyingi 6 ga ko'paytmani olish uchun qo'shilishi kerak bo'lgan raqam (bu holda, 18) 4. Natijada olingan tekshiruv kodi. Bilan bog'liq bo'lgan belgi e.

Tasdiqlash

Olingan ip abcdefe keyin shunga o'xshash protsedura yordamida tasdiqlanishi mumkin:

Belgilarabvdefe
Kod-nuqta0123454
Ikki marta26 (10-tayanch)
10 (6-tayanch)
10 (asos 10)
14 (6-tayanch)
Kamaytirish0221 + 041 + 44
Raqamlar yig'indisi0221454

Raqamlarning umumiy yig'indisi 18. U 6 ga bo'linishi sababli, tekshiruv belgisi yaroqli.

Amalga oshirish

Belgilarni kod nuqtalariga va orqaga qarab xaritalash bir necha usullar bilan amalga oshirilishi mumkin. Oddiy yondashuv (Luhn algoritmiga o'xshash) ASCII kod arifmetikasidan foydalanish. Masalan, ning kirish to'plami berilgan 0 ga 9, kod nuqtasini kerakli belgining ASCII kodidan '0' uchun ASCII kodini olib tashlash orqali hisoblash mumkin. Teskari operatsiya teskari xaritalashni ta'minlaydi. Belgilarning qo'shimcha diapazonlari bilan shartli gaplar yordamida muomala qilish mumkin.

Ketma-ket ketma-ket to'plamlarni qattiq kodlangan holda har ikkala usulda ham xaritalash mumkin switch / case bayonot. Anga o'xshash narsani ishlatish yanada moslashuvchan yondashuvdir assotsiativ qator. Buning ishlashi uchun ikki tomonlama xaritalashni ta'minlash uchun bir juft massiv kerak.

Qo'shimcha imkoniyat - bu qator indekslari har bir belgi bilan bog'liq bo'lgan kod nuqtalari bo'lgan belgilar qatoridan foydalanish. Belgidan kod-nuqtaga xaritalash keyinchalik chiziqli yoki ikkilik qidirish bilan amalga oshirilishi mumkin. Bunday holda, teskari xaritalash oddiy qatorni qidirishdir.

Zaiflik

Ushbu kengaytma asl algoritm bilan bir xil kuchsizlikka ega, ya'ni ketma-ketlikning transpozitsiyasini aniqlay olmaydi <first-valid-character><last-valid-character> ga <last-valid-character><first-valid-character> (yoki aksincha). Bu transpozitsiyaga tengdir 09 ga 90 (dan boshlab tegishli kirish belgilar to'plamini hisobga olgan holda 0 ga 9 tartibda; ... uchun). Ijobiy yozuvda, joriy belgilarning to'plami qanchalik katta bo'lsa, zaiflikning ta'siri shunchalik kichik bo'ladi.

Shuningdek qarang