تحقق من صحة الأرقام وولدها باستخدام خوارزمية لون، المستخدمة عادةً لأرقام بطاقات الائتمان، وأرقام الضمان الاجتماعي الكندية، وأرقام الهوية الأخرى. اختبر ما إذا كان الرقم يمر باختبار لون أو قم بإنشاء أرقام صالحة تتوافق مع الخوارزمية.
خوارزمية لونه، المعروفة أيضًا باسم "خوارزمية المودولوس 10" أو "المود 10"، هي صيغة بسيطة للتحقق من الصحة تُستخدم للتحقق من مجموعة متنوعة من أرقام الهوية، مثل أرقام بطاقات الائتمان، وأرقام التأمين الاجتماعي الكندية، وأرقام IMEI، وأرقام معرف مقدمي الخدمات الوطنية في الولايات المتحدة. تتيح لك هذه الآلة الحاسبة التحقق من صحة الأرقام باستخدام خوارزمية لونه وتوليد أرقام صالحة تمر بفحص لونه.
تعمل خوارزمية لونه على النحو التالي:
إليك تمثيل بصري لخوارزمية لونه:
يمكن التعبير عن خوارزمية لونه رياضيًا كما يلي:
دع يكون الرقم -th، بدءًا من الرقم الأيمن (باستثناء رقم التحقق) والتحرك إلى اليسار. ثم يتم اختيار رقم التحقق بحيث:
حيث هو عملية المودولوس.
تتمتع خوارزمية لونه بتطبيقات متنوعة في مجالات مختلفة:
بينما تُستخدم خوارزمية لونه على نطاق واسع، هناك خوارزميات تحقق أخرى لأغراض مختلفة:
تم إنشاء خوارزمية لونه بواسطة هانز بيتر لونه، عالم الكمبيوتر في 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)) # صحيح
23print(luhn_validate(4532015112830367)) # غير صحيح
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)); // صحيح
30console.log(luhnValidate(4532015112830367)); // غير صحيح
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)); // صحيح
45 System.out.println(luhnValidate(4532015112830367L)); // غير صحيح
46 System.out.println(generateValidNumber(16)); // توليد رقم صالح مكون من 16 رقم
47 }
48}
49
عند تنفيذ خوارزمية لونه، ضع في اعتبارك الحالات الخاصة والاعتبارات التالية:
التحقق من صحة الإدخال: تأكد من أن الإدخال هو سلسلة أرقام صالحة. يجب التعامل مع الأحرف غير الرقمية بشكل مناسب (إما إزالتها أو اعتبارها إدخال غير صالح).
الأصفار الرائدة: يجب أن تعمل الخوارزمية بشكل صحيح مع الأرقام التي تحتوي على أصفار رائدة.
الأرقام الكبيرة: كن مستعدًا للتعامل مع أرقام طويلة جدًا قد تتجاوز سعة أنواع الأعداد الصحيحة القياسية في بعض لغات البرمجة.
الإدخال الفارغ: حدد كيفية تعامل تنفيذك مع السلاسل الفارغة أو المدخلات الفارغة.
مجموعات الأحرف غير القياسية: في بعض التطبيقات، قد تواجه أرقامًا تمثل بأحرف خارج النطاق القياسي 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