Լունայի ալգորիթմ

Լունայի ալգորիթմ (անգլ.՝ Luhn algorithm) - ISO/IEC 7812 ստանդարտի կրեդիիտային քարտի համարի հսկիչ թվանշանի հաշվարկման ալգորիթմ։ Այն չի հանդիսանում կրիպտոգրաֆիկ միջոց, այլ առաջին հերթին նախատեսված է սխալների հայտնաբերման համար, որոնք առաջացել են տվյալների ոչդիտավորյալ աղավաղման արդյունքնում (օրինակ, ձեռքով կրեդիտային քարտի համարի մուտքագրման ժամանակ, հեռախոսով սոցիալական ապահովագրության համարների մասին տվյալների ընդունման ժամանակ և այլն)։ Այն հնարավորություն է տալիս որոշ աստիճանի վստահությամբ դատողություն անել թվերի խմբում սխալի բացակայության մասին, սակայն թույլ չի տալիս այն տեղայնացնել և հայտնաբերված անճշտությունը վերացնել։
Ալգորիթմը մշակվել է IBM ֆիրմայի աշխատակից Հանս Պիտեր Լունայի կողմից, նկարագրվել է 1954 թվականին, արտոնագիր է ստացվել 1960 թվականին։
Հսկիչ թվի հաշվարկման առավել տարածված կիրառումներն են՝

բանկային բոլոր քարտերի համարները,
որոշ ոչզեղջային քարտերի համարները,
սոցիալական ապահովագրության կոդերը,
IMEI – կոդերը,
ռուսական երկաթգծերի վագոնի միասնական 8-նիշ համարների հսկիչ թվի հաշվարկ։Ներկայումս ալգորիթմը հանդիսանում է հանրային սեփականություն։


== Առավելություններն ու թերությունները ==
Ի շնորհիվ իրականացման հեշտության ալգորիթմը գրավում է մինիմալ հաշվարկային հզորություն, հաշվարկի հմտությունների առկայության դեպքում հաշվարկը կարող է կատարվել մտքում։ Միևնույն ժամանակ, Լունայի ալգորիթմը հնարավորություն է տալիս միայն հայտնաբերել սխալները տվյալների խմբում, և այն էլ ոչ բոլոր դեպքերում։ Մի թվի անճշտությունը հայտնաբերվում է։ Պրակտիկորեն հայտնաբերվում են գրեթե բոլոր հաջորդական զույգ թվանշանների տեղափոխությունները (բացառությամբ՝ 09 ↔ 90)։ Չեն կարող հայտնաբերվել երկու հաջորդական թվերի որոշ աղավաղումներ, ինչպես 22 ↔ 55, 33 ↔ 66 և 44 ↔ 77։ Ալգորիթմը տեղեկություն չի տալիս առաջացած սխալի տեղի և բնույթի մասին։
Ալգորիթմը կարող է օգտագործվել ցանկացած երկարության թվերի հաջորդականության համար, սակայն այդ դեպքում պետք է հաշվի առնել, որ մեծ երկարությամբ թվերի համար հավանական է միաժամանակ մի քանի անճշտությունների առկայություն։ Այդպիսի որոշակի սխալներ կարող են բերել ոչճիշտ եզրակացության, որ Լունայի ալգորիթմով հաշվարկված հսկիչ թիվը հաստատում է տվյալների անփոփոխությունը։


== Հսկիչ թվանշանի ստուգման ալգորիթմը ==


=== Պարզեցված ալգորիթմ ===
1. Սկսելով 1-ով (այսինքն՝ 1, 3, 5, 7, 9, . . .) ձախից առաջին թվից այն դեպքում, եթե թվում թվանշանների քանակը զույգ է (ինչպես այս օրինակում, որտեղ այն հավասար է 16-ի), իսկ եթե թվանշանների քանակը կենտ է, այդ դեպքում 1-ով սկսում ենք երկրորդ թվից (այսինքն՝ 2, 4, 6, 8, . . . ) կատարվում է ստուգում, եթե 2•x > 9, այդ դեպքում արտադրյալից հանվում է 9, հակառակ դեպքում 2•x արտադրյալը թողնում ենք առանց փոփոխության։
Օրինակ,

4 5 6 1   2 6 1 2   1 2 3 4   5 4 6 4
8   12    4   2    2   6    10  12
8   3    4   2    2   6    1   3

2. Այնուհետև բոլոր թվերը գումարվում են։

8+5+3+1 + 4+6+2+2 + 2+2+6+4 + 1+4+3+4 = 57

3. Ստացված թիվը պետք է լինի 10-ի բազմապատիկ (40, 50, 60, 70, . . .)։
Օրինակում վերջին թիվը հսկիչ թվանշանն է։ Որպեսզի համարն ըստ Լունայի ալգորիթմի լինի ճիշտ, հսկիչ թվանշանը պետք է հավասար լինի 7-ի։

4 5 6 1   2 6 1 2   1 2 3 4   5 4 6 7
8   12    4   2    2   6    10  12
8   3    4   2    2   6    1   3

8+5+3+1 + 4+6+2+2 + 2+2+6+4 + 1+4+3+7 = 60


=== Մշակողի կողմից նկարագրված ինքնատիպ ալգորիթմ ===
Ստուգվող հաջորդականության թվանշանները համարակալվում են աջից ձախ։
Թվանշանները, որոնք գտնվում են կենտ տեղերում, մնում են անփոփոխ։
Թվանշանները, որոնք գտնվում են զույգ տեղերում, բազմապատկվում են 2-ով։
Եթե այդպիսի բազմապատկման արդյունքում ստացվում է 9-ից մեծ թիվ, ապա այն փոխարինվում է միանիշ թվով, որն առաջանում է բազմապատկման արդյունքում ստացված թվի թվանշանների գումարից, այսինքն՝ թվանշան։
Ձևափոխման արդյունքում ստացված բոլոր թվանշանները գումարվում են։ Եթե գումարը 10-ի բազմապատիկ է, ապա սկզբնական տվյալները ճիշտ են։


== Հսկիչ թվանշանի հաշվման ալգորիթմը ==
Num[1..N] - ը քարտի համարն է, Num[N] - հսկիչ թվանշանն է։

sum = 0
for i = 1 to N-1 do
 p = Num[N-i]  
 if (i mod 2 <> 0) then
  p = 2*p
  if (p > 9) then 
   p = p - 9
  end if
 end if
 sum = sum + p
next i
//լրացվում է մինչև 10-ը 
sum = 10 - (sum mod 10)
if (sum == 10) then 
 sum = 0
end if
Num[N] = sum