2009-07-16 7 views

risposta

8
int checkSum(const std::vector<int>& code) const 
{ 
    if (code.size() < 8) return false; 

    for(SIZE_T i = 0; i< code.size(); i++) 
    { 
     if(code[i] < 0) return false; 
    } 

    int sum1 = code[1] + code[3] + code[5] 
    int sum2 = 3 * (code[0] + code[2] + code[4] + code[6]); 

    int checksum_value = sum1 + sum2; 
    int checksum_digit = 10 - (checksum_value % 10); 
    if (checksum_digit == 10) checksum_digit = 0; 

    return checksum_digit; 
} 
+0

questo è corretto - sum1 dovrebbe essere (codice [1] + codice [3] + codice [5]), sum2 dovrebbe essere di 3 * (codice [0] + codice [2] + codice [4] + codice [6]) –

+0

OK. Testato solo con EAN13. Sembra che i pesi iniziali siano diversi in EAN8 e EAN13 ... – SuperPro

+1

Le cifre sono contate da destra, quindi poiché 8 è pari e 13 è dispari, hanno pesi diversi. Grazie per l'editing, rimosso a downvote! –

11

L'algoritmo è trattato in questo wikipedia article on EAN, notare che EAN-8 è calcolato allo stesso modo di EAN-13.

Ecco un esempio pratico da http://www.barcodeisland.com/ean8.phtml:

Supponendo vogliamo codificare il messaggio a 7 cifre "5.512.345", vorremmo calcolare il checksum nel seguente modo:

Barcode   5  5  1  2  3  4  5 
Odd/Even Pos? O  E  O  E  O  E  O 
Weighting  3  1  3  1  3  1  3 
Calculation 5*3 5*1 1*3 2*1 3*3 4*1 5*3 
Weighted Sum 15  5  3  2  9  4 15 

Il totale è 15 + 5 + 3 + 2 + 9 + 4 + 15 = 53. 7 deve essere aggiunto a 53 per produrre un numero equamente divisibile per 10, quindi la cifra di checksum è 7 e il valore del codice a barre completato è "55123457".

string code="55123457"; 

int sum1 = code[1] + code[3] + code[5] 
int sum2 = 3 * (code[0] + code[2] + code[4] + code[6]); 
int checksum_value = sum1 + sum2; 

int checksum_digit = 10 - (checksum_value % 10); 
if (checksum_digit == 10) 
    checksum_digit = 0; 
5

Scusate riapertura

Java versione

public int checkSum(String code){ 
     int val=0; 
     for(int i=0;i<code.length();i++){ 
      val+=((int)Integer.parseInt(code.charAt(i)+""))*((i%2==0)?1:3); 
     } 

     int checksum_digit = 10 - (val % 10); 
     if (checksum_digit == 10) checksum_digit = 0; 

     return checksum_digit; 
    } 
4

Risvegliato con una versione C#:

public static bool IsValidEan13(string eanBarcode) 
    { 
     return IsValidEan(eanBarcode, 13); 
    } 

    public static bool IsValidEan12(string eanBarcode) 
    { 
     return IsValidEan(eanBarcode, 12); 
    } 

    public static bool IsValidEan14(string eanBarcode) 
    { 
     return IsValidEan(eanBarcode, 14); 
    } 

    public static bool IsValidEan8(string eanBarcode) 
    { 
     return IsValidEan(eanBarcode, 8); 
    } 

    private static bool IsValidEan(string eanBarcode, int length) 
    { 
     if (eanBarcode.Length != length) return false; 
     var allDigits = eanBarcode.Select(c => int.Parse(c.ToString(CultureInfo.InvariantCulture))).ToArray(); 
     var s = length%2 == 0 ? 3 : 1; 
     var s2 = s == 3 ? 1 : 3; 
     return allDigits.Last() == (10 - (allDigits.Take(length-1).Select((c, ci) => c*(ci%2 == 0 ? s : s2)).Sum()%10))%10; 
    } 
1

Ecco la versione di Java per EAN13

private int calcChecksum(String first12digits) { 
    char[] char12digits = first12digits.toCharArray(); 
    int[] ean13 = {1,3}; 
    int sum = 0; 
    for(int i = 0 ; i<char12digits.length; i++){ 
     sum += Character.getNumericValue(char12digits[i]) * ean13[i%2]; 
    } 

    int checksum = 10 - sum%10; 
    if(checksum == 10){ 
     checksum = 0; 
    } 

    return checksum; 
} 
1
class GTIN(object): 

    def __init__(self, barcode=''): 
     self.barcode = barcode 

    def __checkDigit(self, digits): 
      total = sum(digits) + sum(map(lambda d: d*2, digits[-1::-2])) 
      return (10 - (total % 10)) % 10 

    def validateCheckDigit(self, barcode=''): 
     barcode = (barcode if barcode else self.barcode) 
     if len(barcode) in (8,12,13,14) and barcode.isdigit(): 
      digits = map(int, barcode) 
      checkDigit = self.__checkDigit(digits[0:-1]) 
      return checkDigit == digits[-1] 
     return False 

    def addCheckDigit(self, barcode=''): 
     barcode = (barcode if barcode else self.barcode) 
     if len(barcode) in (7,11,12,13) and barcode.isdigit(): 
      digits = map(int, barcode) 
      return barcode + str(self.__checkDigit(digits)) 
     return '' 
2

Ecco una versione di MySQL per EAN13:

 
    SET @first12digits="123456789012"; 
    SELECT @first12digits, 
IF (
    (@check:=10-MOD(
     (CAST(SUBSTRING(@first12digits, 1, 1) AS DECIMAL))+ 
     (CAST(SUBSTRING(@first12digits, 2, 1) AS DECIMAL) * 3)+ 
     (CAST(SUBSTRING(@first12digits, 3, 1) AS DECIMAL))+ 
     (CAST(SUBSTRING(@first12digits, 4, 1) AS DECIMAL) * 3)+ 
     (CAST(SUBSTRING(@first12digits, 5, 1) AS DECIMAL))+ 
     (CAST(SUBSTRING(@first12digits, 6, 1) AS DECIMAL) * 3)+ 
     (CAST(SUBSTRING(@first12digits, 7, 1) AS DECIMAL))+ 
     (CAST(SUBSTRING(@first12digits, 8, 1) AS DECIMAL) * 3)+ 
     (CAST(SUBSTRING(@first12digits, 9, 1) AS DECIMAL))+ 
     (CAST(SUBSTRING(@first12digits, 10, 1) AS DECIMAL) * 3)+ 
     (CAST(SUBSTRING(@first12digits, 11, 1) AS DECIMAL))+ 
     (CAST(SUBSTRING(@first12digits, 12, 1) AS DECIMAL) * 3) 
    ,10)) = 10, 0, @check 
    ) AS checkDigit; 

c'era un bug. Se Calc risultato = 10, quindi selezionare cifra = 0.
Di seguito una versione migliore per EAN14.



    SET @first13digits="1234567890123"; 
    SELECT @txCode13:[email protected], 
     @iCheck := (
      10 - (
      (
       MID(@txCode13, 2, 1) + 
       MID(@txCode13, 4, 1) + 
       MID(@txCode13, 6, 1) + 
       MID(@txCode13, 8, 1) + 
       MID(@txCode13, 10, 1) + 
       MID(@txCode13, 12, 1) 
      ) + (
       MID(@txCode13, 1, 1) + 
       MID(@txCode13, 3, 1) + 
       MID(@txCode13, 5, 1) + 
       MID(@txCode13, 7, 1) + 
       MID(@txCode13, 9, 1) + 
       MID(@txCode13, 11, 1) + 
       MID(@txCode13, 13, 1) 
       ) * 3) % 10 
      ) AS iCheck, 
     @iCheckDigit := IF(@iCheck = 10, 0, @iCheck) AS checkDigit, 
     CONCAT(@t 

xCode13, CAST(@iCheckDigit AS CHAR)) AS EAN14WithCheck 
+0

C'è un bug.Se calc risultato = 10, la cifra di controllo è 0. –

0

Java Version:

Funziona perfettamente

public static int checkSum(String code){ 
     int val=0; 
     for(int i=0; i<code.length()-1; i++){ 
      val+=((int)Integer.parseInt(code.charAt(i)+""))*((i%2==0)?1:3); 
     } 

     int checksum_digit = (10 - (val % 10)) % 10; 

     return checksum_digit; 
    } 
0

Python EAN13 calcolo di verifica cifre sulla base della funzione Java di Najoua Mahi:

def generateEAN13CheckDigit(self, first12digits): 
    charList = [char for char in first12digits] 
    ean13 = [1,3] 
    total = 0 
    for order, char in enumerate(charList): 
     total += int(char) * ean13[order % 2] 

    checkDigit = 10 - total % 10 
    if (checkDigit == 10): 
     return 0 
    return checkDigit 
0

Questo funziona sia su EAN 13 e EAN8:

public static String generateEAN(String barcode) { 
    int first = 0; 
    int second = 0; 

    if(barcode.length() == 7 || barcode.length() == 12) { 

     for (int counter = 0; counter < barcode.length() - 1; counter++) { 
      first = (first + Integer.valueOf(barcode.substring(counter, counter + 1))); 
      counter++; 
      second = (second + Integer.valueOf(barcode.substring(counter, counter + 1))); 
     } 
     second = second * 3; 
     int total = second + first; 
     int roundedNum = Math.round((total + 9)/10 * 10); 

     barcode = barcode + String.valueOf(roundedNum - total); 
    } 
    return barcode; 
} 
0

Oggi ho bisogno di una versione di PHP, mi ricordo di questa pagina e copiare dalla versione di Java. Grazie.

function getEAN13($txEan12) 
    { 
    $iVal=0; 

    for($i=0; $i<strlen($txEan12); $i++) 
     { 
     $iSingleCharVal = intval(substr($txEan12, $i, 1));  // extract value of one char 
     $iSingleCharMult = $iSingleCharVal * ($i%2==0 ? 1 : 3); // calculate depending from position 
     $iVal+= $iSingleCharMult; // sum 
     } 

    $iCheckDigit = 10 - ($iVal % 10); 
    if ($iCheckDigit == 10) $iCheckDigit = 0; 
    return $txEan12 . $iCheckDigit; 
    }