Whiz Tools

Υπολογιστής Αλγορίθμου Luhn

Υπολογιστής Αλγορίθμου Luhn

Εισαγωγή

Ο αλγόριθμος Luhn, γνωστός και ως "αλγόριθμος υπολοίπου 10" ή "mod 10", είναι μια απλή φόρμουλα ελέγχου που χρησιμοποιείται για την επικύρωση διαφόρων αριθμών ταυτοποίησης, όπως αριθμοί πιστωτικών καρτών, Καναδικοί αριθμοί κοινωνικής ασφάλισης, αριθμοί IMEI και αριθμοί Εθνικού Παρόχου Ταυτοποίησης στις Ηνωμένες Πολιτείες. Αυτός ο υπολογιστής σας επιτρέπει να επικυρώνετε αριθμούς χρησιμοποιώντας τον αλγόριθμο Luhn και να δημιουργείτε έγκυρους αριθμούς που περνούν τον έλεγχο Luhn.

Πώς Λειτουργεί ο Αλγόριθμος Luhn

Ο αλγόριθμος Luhn λειτουργεί ως εξής:

  1. Ξεκινώντας από το δεξιότερο ψηφίο (εξαιρώντας το ψηφίο ελέγχου) και κινούμενοι προς τα αριστερά, διπλασιάστε την τιμή κάθε δεύτερου ψηφίου.
  2. Εάν το αποτέλεσμα αυτής της διαδικασίας διπλασιασμού είναι μεγαλύτερο από 9, αφαιρέστε 9 από το αποτέλεσμα.
  3. Αθροίστε όλα τα ψηφία στην προκύπτουσα ακολουθία.
  4. Εάν το συνολικό υπόλοιπο 10 είναι ίσο με 0 (εάν το συνολικό καταλήγει σε μηδέν), τότε ο αριθμός είναι έγκυρος σύμφωνα με τον τύπο Luhn. Διαφορετικά, δεν είναι έγκυρος.

Ακολουθεί μια οπτική αναπαράσταση του αλγορίθμου Luhn:

1. Διπλασιάστε κάθε δεύτερο ψηφίο 2. Αθροίστε τα ψηφία (9 για διπλασιασμένα > 9) 3. Υπολογίστε το συνολικό άθροισμα 4. Ελέγξτε αν το άθροισμα % 10 == 0

Τύπος

Ο αλγόριθμος Luhn μπορεί να εκφραστεί μαθηματικά ως εξής:

Έστω did_i το ii-οστό ψηφίο, μετρώντας από το δεξιότερο ψηφίο (εξαιρώντας το ψηφίο ελέγχου) και κινούμενοι αριστερά. Τότε το ψηφίο ελέγχου d0d_0 επιλέγεται έτσι ώστε:

(2d2nmod9+d2n1+2d2n2mod9+d2n3++2d2mod9+d1+d0)mod10=0(2d_{2n} \bmod 9 + d_{2n-1} + 2d_{2n-2} \bmod 9 + d_{2n-3} + \cdots + 2d_2 \bmod 9 + d_1 + d_0) \bmod 10 = 0

Όπου mod\bmod είναι η λειτουργία υπολοίπου.

Χρήσεις

Ο αλγόριθμος Luhn έχει διάφορες εφαρμογές σε διαφορετικά πεδία:

  1. Επικύρωση Αριθμών Πιστωτικών Καρτών: Οι περισσότεροι αριθμοί πιστωτικών καρτών επικυρώνονται χρησιμοποιώντας τον αλγόριθμο Luhn.
  2. Καναδικοί Αριθμοί Κοινωνικής Ασφάλισης: Ο αλγόριθμος Luhn χρησιμοποιείται για την επαλήθευση της εγκυρότητας αυτών των αριθμών ταυτοποίησης.
  3. Αριθμοί IMEI: Οι αριθμοί IMEI κινητών τηλεφώνων περιλαμβάνουν ένα ψηφίο ελέγχου που επικυρώνεται από τον αλγόριθμο Luhn.
  4. Αριθμοί Εθνικού Παρόχου Ταυτοποίησης (NPI): Χρησιμοποιούμενοι στο σύστημα υγειονομικής περίθαλψης των Ηνωμένων Πολιτειών, αυτοί οι αριθμοί επικυρώνονται χρησιμοποιώντας τον αλγόριθμο Luhn.
  5. ISBNs: Ορισμένοι αριθμοί ISBN-10 χρησιμοποιούν μια παραλλαγή του αλγορίθμου Luhn για επικύρωση.

Εναλλακτικές

Ενώ ο αλγόριθμος Luhn είναι ευρέως χρησιμοποιούμενος, υπάρχουν και άλλοι αλγόριθμοι ελέγχου για διαφορετικούς σκοπούς:

  1. Αλγόριθμος Damm: Ένας άλλος αλγόριθμος ψηφίου ελέγχου που ανιχνεύει όλα τα σφάλματα ενός ψηφίου και όλα τα σφάλματα διπλής μετατόπισης.
  2. Αλγόριθμος Verhoeff: Ένας πιο πολύπλοκος αλγόριθμος ελέγχου που ανιχνεύει όλα τα σφάλματα ενός ψηφίου και τις περισσότερες διπλές μετατοπίσεις.
  3. Ψηφίο ελέγχου ISBN-13: Χρησιμοποιεί έναν διαφορετικό αλγόριθμο από το ISBN-10, ο οποίος βασίζεται στον αλγόριθμο Luhn.

Ιστορία

Ο αλγόριθμος Luhn δημιουργήθηκε από τον Hans Peter Luhn, έναν επιστήμονα υπολογιστών της IBM, το 1954. Ο Luhn ήταν πρωτοπόρος στον τομέα της επιστήμης των πληροφοριών και πιστώνεται με πολλές καινοτομίες, συμπεριλαμβανομένου του συστήματος ευρετηρίασης KWIC (Key Word In Context).

Ο αλγόριθμος σχεδιάστηκε αρχικά για να προστατεύει από τυχαία σφάλματα, όχι από κακόβουλες επιθέσεις. Είναι σημαντικό να σημειωθεί ότι ενώ ο αλγόριθμος Luhn μπορεί να ανιχνεύσει πολλά κοινά σφάλματα, δεν είναι μια ασφαλής μορφή κρυπτογράφησης και δεν θα πρέπει να βασίζεστε σε αυτόν για σκοπούς ασφάλειας δεδομένων.

Παρά την ηλικία του, ο αλγόριθμος Luhn παραμένει ευρέως χρησιμοποιούμενος λόγω της απλότητας και της αποτελεσματικότητάς του στην ανίχνευση κοινών σφαλμάτων καταγραφής.

Παραδείγματα Υλοποίησης

Ακολουθούν μερικά παραδείγματα κώδικα για την υλοποίηση του αλγορίθμου Luhn σε διάφορες γλώσσες προγραμματισμού:

import random

def luhn_validate(number):
    digits = [int(d) for d in str(number)]
    checksum = 0
    for i in range(len(digits) - 1, -1, -1):
        d = digits[i]
        if (len(digits) - i) % 2 == 0:
            d = d * 2
            if d > 9:
                d -= 9
        checksum += d
    return checksum % 10 == 0

def generate_valid_number(length):
    digits = [random.randint(0, 9) for _ in range(length - 1)]
    checksum = sum(digits[::2]) + sum(sum(divmod(d * 2, 10)) for d in digits[-2::-2])
    check_digit = (10 - (checksum % 10)) % 10
    return int(''.join(map(str, digits + [check_digit])))

## Παράδειγμα χρήσης:
print(luhn_validate(4532015112830366))  # True
print(luhn_validate(4532015112830367))  # False
print(generate_valid_number(16))  # Δημιουργεί έναν έγκυρο 16-ψήφιο αριθμό
function luhnValidate(number) {
    const digits = number.toString().split('').map(Number);
    let checksum = 0;
    for (let i = digits.length - 1; i >= 0; i--) {
        let d = digits[i];
        if ((digits.length - i) % 2 === 0) {
            d *= 2;
            if (d > 9) d -= 9;
        }
        checksum += d;
    }
    return checksum % 10 === 0;
}

function generateValidNumber(length) {
    const digits = Array.from({length: length - 1}, () => Math.floor(Math.random() * 10));
    const checksum = digits.reduce((sum, digit, index) => {
        if ((length - 1 - index) % 2 === 0) {
            digit *= 2;
            if (digit > 9) digit -= 9;
        }
        return sum + digit;
    }, 0);
    const checkDigit = (10 - (checksum % 10)) % 10;
    return parseInt(digits.join('') + checkDigit);
}

// Παράδειγμα χρήσης:
console.log(luhnValidate(4532015112830366));  // true
console.log(luhnValidate(4532015112830367));  // false
console.log(generateValidNumber(16));  // Δημιουργεί έναν έγκυρο 16-ψήφιο αριθμό
import java.util.Random;

public class LuhnValidator {
    public static boolean luhnValidate(long number) {
        String digits = String.valueOf(number);
        int checksum = 0;
        boolean isEven = true;
        for (int i = digits.length() - 1; i >= 0; i--) {
            int digit = Character.getNumericValue(digits.charAt(i));
            if (isEven) {
                digit *= 2;
                if (digit > 9) digit -= 9;
            }
            checksum += digit;
            isEven = !isEven;
        }
        return checksum % 10 == 0;
    }

    public static long generateValidNumber(int length) {
        Random random = new Random();
        long[] digits = new long[length - 1];
        for (int i = 0; i < length - 1; i++) {
            digits[i] = random.nextInt(10);
        }
        long checksum = 0;
        for (int i = digits.length - 1; i >= 0; i--) {
            long digit = digits[i];
            if ((length - 1 - i) % 2 == 0) {
                digit *= 2;
                if (digit > 9) digit -= 9;
            }
            checksum += digit;
        }
        long checkDigit = (10 - (checksum % 10)) % 10;
        long result = 0;
        for (long digit : digits) {
            result = result * 10 + digit;
        }
        return result * 10 + checkDigit;
    }

    public static void main(String[] args) {
        System.out.println(luhnValidate(4532015112830366L));  // true
        System.out.println(luhnValidate(4532015112830367L));  // false
        System.out.println(generateValidNumber(16));  // Δημιουργεί έναν έγκυρο 16-ψήφιο αριθμό
    }
}

Άκρες και Ειδικές Σκέψεις

Κατά την υλοποίηση του αλγορίθμου Luhn, εξετάστε τις παρακάτω άκρες και ειδικές σκέψεις:

  1. Επικύρωση Εισόδου: Βεβαιωθείτε ότι η είσοδος είναι μια έγκυρη ακολουθία αριθμών. Μη ψηφιακοί χαρακτήρες θα πρέπει να αντιμετωπίζονται κατάλληλα (είτε να αφαιρούνται είτε να θεωρούνται ως μη έγκυρη είσοδος).

  2. Ηγετικά Μηδενικά: Ο αλγόριθμος θα πρέπει να λειτουργεί σωστά με αριθμούς που έχουν ηγετικά μηδενικά.

  3. Μεγάλοι Αριθμοί: Να είστε προετοιμασμένοι να χειριστείτε πολύ μεγάλους αριθμούς που μπορεί να υπερβαίνουν την ικανότητα των τυπικών τύπων ακέραιων αριθμών σε ορισμένες γλώσσες προγραμματισμού.

  4. Κενή Είσοδος: Ορίστε πώς θα πρέπει να χειρίζεται η υλοποίησή σας κενές ακολουθίες ή null εισόδους.

  5. Μη Τυποποιημένα Σύνολα Χαρακτήρων: Σε ορισμένες εφαρμογές, μπορεί να συναντήσετε αριθμούς που αναπαρίστανται με χαρακτήρες εκτός του τυπικού εύρους 0-9. Ορίστε πώς θα πρέπει να χειρίζονται αυτοί.

  6. Σκέψεις Απόδοσης: Για εφαρμογές που χρειάζονται γρήγορα να επικυρώνουν μεγάλους αριθμούς εισόδου, εξετάστε την πιθανότητα βελτιστοποίησης της υλοποίησης του αλγορίθμου.

Αριθμητικά Παραδείγματα

  1. Έγκυρος Αριθμός Πιστωτικής Κάρτας:

    • Αριθμός: 4532015112830366
    • Έλεγχος Luhn: Έγκυρος
  2. Μη Έγκυρος Αριθμός Πιστωτικής Κάρτας:

    • Αριθμός: 4532015112830367
    • Έλεγχος Luhn: Μη Έγκυρος
  3. Έγκυρος Καναδικός Αριθμός Κοινωνικής Ασφάλισης:

    • Αριθμός: 046 454 286
    • Έλεγχος Luhn: Έγκυρος
  4. Μη Έγκυρος Αριθμός IMEI:

    • Αριθμός: 490154203237518
    • Έλεγχος Luhn: Μη Έγκυρος

Δοκιμαστικές Περιπτώσεις

Για να επαληθεύσετε την υλοποίηση του αλγορίθμου Luhn, μπορείτε να χρησιμοποιήσετε τις παρακάτω δοκιμαστικές περιπτώσεις:

def test_luhn_algorithm():
    assert luhn_validate(4532015112830366) == True
    assert luhn_validate(4532015112830367) == False
    assert luhn_validate(79927398713) == True
    assert luhn_validate(79927398714) == False
    
    # Δοκιμάστε τους παραγόμενους αριθμούς
    for _ in range(10):
        assert luhn_validate(generate_valid_number(16)) == True
    
    print("Όλες οι δοκιμές πέρασαν!")

test_luhn_algorithm()

Αναφορές

  1. Luhn, H. P. (1960). "Υπολογιστής για την Επαλήθευση Αριθμών". Δίπλωμα ευρεσιτεχνίας ΗΠΑ 2,950,048.
  2. Gallian, Joseph. "Τα Μαθηματικά των Αριθμών Ταυτοποίησης." Το Περιοδικό Κολλεγίων Μαθηματικών, τόμος 22, αριθμός 3, 1991, σελ. 194–202. JSTOR, www.jstor.org/stable/2686878.
  3. "ISO/IEC 7812-1:2017". Διεθνής Οργάνωση Τυποποίησης. Ανακτήθηκε 2 Αυγούστου 2024.
  4. Knuth, Donald. "Η Τέχνη του Υπολογιστικού Προγραμματισμού, Τόμος 2: Αλγόριθμοι Ημι-Αριθμητικοί". Addison-Wesley, 1997.
Feedback