אמת וייצר מספרים באמצעות אלגוריתם לון, הנמצא בשימוש נפוץ עבור מספרי כרטיסי אשראי, מספרי ביטוח לאומי קנדי ומספרי זיהוי אחרים. בדוק אם מספר עובר את בדיקת לון או ייצר מספרים תקפים העומדים באלגוריתם.
אלגוריתם לון, הידוע גם כ"מודולוס 10" או "מוד 10", הוא נוסחת בדיקה פשוטה המשמשת לאימות מגוון מספרי זיהוי, כגון מספרי כרטיסי אשראי, מספרי ביטוח לאומי קנדים, מספרי IMEI ומספרי ספק לאומי בארצות הברית. מחשבון זה מאפשר לך לאמת מספרים באמצעות אלגוריתם לון וליצור מספרים חוקיים שעוברים את בדיקת לון.
אלגוריתם לון עובד כך:
הנה ייצוג חזותי של אלגוריתם לון:
אלגוריתם לון ניתן לביטוי מתמטי כך:
יהי הספרה ה--ית, סופרים מהספרה הימנית ביותר (ללא ספרת הבדיקה) והולכים שמאלה. אז ספרת הבדיקה נבחרת כך ש:
כאשר היא פעולה מודולו.
לאלגוריתם לון יש יישומים שונים בתחומים שונים:
בעוד שאלגוריתם לון בשימוש נרחב, ישנם אלגוריתמים אחרים לבדיקה למטרות שונות:
אלגוריתם לון נוצר על ידי האנס פטר לון, מדען מחשבים ב-IBM, בשנת 1954. לון היה חלוץ בתחום מדעי המידע ומיוחסות לו מספר חידושים, כולל מערכת אינדוקס KWIC (מילת מפתח בהקשר).
האלגוריתם נועד במקור להגן מפני שגיאות מקריות, ולא מפני התקפות זדוניות. חשוב לציין כי בעוד שאלגוריתם לון יכול לזהות רבות מהשגיאות הנפוצות, הוא אינו צורת הצפנה בטוחה ואין לסמוך עליו למטרות אבטחת נתונים.
למרות גילו, אלגוריתם לון נשאר בשימוש נרחב בשל הפשטות והיעילות שלו בלכידת שגיאות העתקה נפוצות.
הנה כמה דוגמאות קוד ליישום אלגוריתם לון בשפות תכנות שונות:
1import random
2
3def luhn_validate(number):
4 digits = [int(d) for d in str(number)]
5 checksum = 0
6 for i in range(len(digits) - 1, -1, -1):
7 d = digits[i]
8 if (len(digits) - i) % 2 == 0:
9 d = d * 2
10 if d > 9:
11 d -= 9
12 checksum += d
13 return checksum % 10 == 0
14
15def generate_valid_number(length):
16 digits = [random.randint(0, 9) for _ in range(length - 1)]
17 checksum = sum(digits[::2]) + sum(sum(divmod(d * 2, 10)) for d in digits[-2::-2])
18 check_digit = (10 - (checksum % 10)) % 10
19 return int(''.join(map(str, digits + [check_digit])))
20
21## דוגמת שימוש:
22print(luhn_validate(4532015112830366)) # True
23print(luhn_validate(4532015112830367)) # False
24print(generate_valid_number(16)) # יוצר מספר חוקי בן 16 ספרות
25
1function luhnValidate(number) {
2 const digits = number.toString().split('').map(Number);
3 let checksum = 0;
4 for (let i = digits.length - 1; i >= 0; i--) {
5 let d = digits[i];
6 if ((digits.length - i) % 2 === 0) {
7 d *= 2;
8 if (d > 9) d -= 9;
9 }
10 checksum += d;
11 }
12 return checksum % 10 === 0;
13}
14
15function generateValidNumber(length) {
16 const digits = Array.from({length: length - 1}, () => Math.floor(Math.random() * 10));
17 const checksum = digits.reduce((sum, digit, index) => {
18 if ((length - 1 - index) % 2 === 0) {
19 digit *= 2;
20 if (digit > 9) digit -= 9;
21 }
22 return sum + digit;
23 }, 0);
24 const checkDigit = (10 - (checksum % 10)) % 10;
25 return parseInt(digits.join('') + checkDigit);
26}
27
28// דוגמת שימוש:
29console.log(luhnValidate(4532015112830366)); // true
30console.log(luhnValidate(4532015112830367)); // false
31console.log(generateValidNumber(16)); // יוצר מספר חוקי בן 16 ספרות
32
1import java.util.Random;
2
3public class LuhnValidator {
4 public static boolean luhnValidate(long number) {
5 String digits = String.valueOf(number);
6 int checksum = 0;
7 boolean isEven = true;
8 for (int i = digits.length() - 1; i >= 0; i--) {
9 int digit = Character.getNumericValue(digits.charAt(i));
10 if (isEven) {
11 digit *= 2;
12 if (digit > 9) digit -= 9;
13 }
14 checksum += digit;
15 isEven = !isEven;
16 }
17 return checksum % 10 == 0;
18 }
19
20 public static long generateValidNumber(int length) {
21 Random random = new Random();
22 long[] digits = new long[length - 1];
23 for (int i = 0; i < length - 1; i++) {
24 digits[i] = random.nextInt(10);
25 }
26 long checksum = 0;
27 for (int i = digits.length - 1; i >= 0; i--) {
28 long digit = digits[i];
29 if ((length - 1 - i) % 2 == 0) {
30 digit *= 2;
31 if (digit > 9) digit -= 9;
32 }
33 checksum += digit;
34 }
35 long checkDigit = (10 - (checksum % 10)) % 10;
36 long result = 0;
37 for (long digit : digits) {
38 result = result * 10 + digit;
39 }
40 return result * 10 + checkDigit;
41 }
42
43 public static void main(String[] args) {
44 System.out.println(luhnValidate(4532015112830366L)); // true
45 System.out.println(luhnValidate(4532015112830367L)); // false
46 System.out.println(generateValidNumber(16)); // יוצר מספר חוקי בן 16 ספרות
47 }
48}
49
בעת יישום אלגוריתם לון, שקול את המקרים הקצה והשיקולים המיוחדים הבאים:
אימות קלט: ודא שהקלט הוא מיתר מספר חוקי. יש לטפל באותיות שאינן ספרות כראוי (או להסיר אותן או להתייחס אליהן כקלט לא חוקי).
אפסי מובילים: האלגוריתם צריך לעבוד כראוי עם מספרים שיש להם אפסים מובילים.
מספרים גדולים: היה מוכן להתמודד עם מספרים מאוד ארוכים שעשויים לחרוג מהקיבולת של סוגי מספרים סטנדרטיים בחלק משפות התכנות.
קלט ריק: הגדר כיצד היישום שלך צריך להתמודד עם מיתרים ריקים או קלטים null.
קבוצות תווים לא סטנדרטיות: בחלק מהיישומים, ייתכן שתיתקל במספרים המיוצגים עם תווים מחוץ לטווח הסטנדרטי 0-9. הגדר כיצד יש לטפל בזה.
שיקולי ביצועים: עבור יישומים שצריכים לאמת מספרים רבים של קלטים במהירות, שקול לייעל את יישום האלגוריתם.
מספר כרטיס אשראי חוקי:
מספר כרטיס אשראי לא חוקי:
מספר חוקי של ביטוח לאומי קנדי:
מספר IMEI לא חוקי:
כדי לאמת את היישום של אלגוריתם לון, תוכל להשתמש במקרים הבאים:
1def test_luhn_algorithm():
2 assert luhn_validate(4532015112830366) == True
3 assert luhn_validate(4532015112830367) == False
4 assert luhn_validate(79927398713) == True
5 assert luhn_validate(79927398714) == False
6
7 # בדוק מספרים שנוצרו
8 for _ in range(10):
9 assert luhn_validate(generate_valid_number(16)) == True
10
11 print("כל הבדיקות עברו!")
12
13test_luhn_algorithm()
14