Avatar billede straszek Praktikant
14. januar 2007 - 16:36 Der er 39 kommentarer og
2 løsninger

validering af ean-nummer

ER der nogen der ligger inde med et stykke kode der kan validere om et EAN-nummer (de numre der bruges til e-fakturering til de offentlige) er gyldigt?

Altså en validering af om strengen $ean er gyldig i forhold til EAN syntaxen?
Avatar billede shooka Nybegynder
14. januar 2007 - 17:02 #1
"EAN-nummeret er 13-cifret og skrives uden bindestreger, punktummer, kommaer eller lignende. Med andre ord skal nummeret skrives i én uafbrudt talrække."

Kilde: Økonomistyrelsen, http://www.oes.dk/sw7319.asp

Her er der en kode, som fungerer:

$valean = ereg("^[0-9]{13}$", $ean);

if($valean)
{
// EAN-nummeret er korrekt.
}
else
{
// EAN-nummeret er forkert.
}
Avatar billede straszek Praktikant
14. januar 2007 - 17:06 #2
Ja, det er jeg godt klar over, men der mere i det en det; f.x. så starter ean-numre med 57.  $ean=1234567891234; indeholder 13 tal, men er ikke et gyldigt ean-nummer
Avatar billede erikjacobsen Ekspert
14. januar 2007 - 17:07 #3
Avatar billede straszek Praktikant
14. januar 2007 - 17:10 #4
fint, det ligger lidt ud over mine evner at lave det om til php-kode, er der nogen der kan være behjælpelig?
Avatar billede coderdk Praktikant
14. januar 2007 - 17:59 #5
Du har strlen til at finde længden, du kan tilgå $ean[0], $ean[6] osv - hvad er det du har problemer med?
Avatar billede straszek Praktikant
14. januar 2007 - 18:56 #6
Jeg har problemer med at lave algoritmen som erikjacobsen omtaler, om til noget jeg kan bruge i php
Avatar billede coderdk Praktikant
14. januar 2007 - 19:36 #7
Mon ikke du så skulle poste i http://www.eksperten.dk/spm/Opgaver/Programmeringsopgaver/PHP/ - Her hjælper vi glædeligt hvis du sidder fast i noget ;)
Avatar billede shooka Nybegynder
14. januar 2007 - 19:44 #8
Her er koden til algoritmen:

<?php
$ean = "9101456790226";
$valean = ereg("^[0-9]{13}$", $ean);

if($valean)
{
$odd = ($ean[0]+$ean[2]+$ean[4]+$ean[6]+$ean[8]+$ean[10]+$ean[12])*3;
$even = $ean[1]+$ean[3]+$ean[5]+$ean[7]+$ean[9]+$ean[11];
$sum = $odd + $even;
$result = $sum/10;
$result2 = explode(".", $result);
$result3 = 10-$result2[1];

echo $result3;
}

?>
Avatar billede jensgram Nybegynder
14. januar 2007 - 19:46 #9
Ja, her kommer også en upædagogisk :P

<?php

function getEanCheckDigit($param) {
    $sum = 0;
    $odd = true;

    for ($i = 11; $i >= 0; $i--) {
        if ($odd) {
            $sum += 3 * intval(substr($param, $i, 1));
        } else {
            $sum += intval(substr($param, $i, 1));
        }
        $odd = !$odd;
    }

    return $sum % 10;
}

function validateEan($ean) {
    return (substr($ean, 12) == getEanCheckDigit(substr($ean, 0, 12)));
}

print getEanCheckDigit(101742256780);
var_dump(validateEan(1017422567805));

?>
Avatar billede jensgram Nybegynder
14. januar 2007 - 19:48 #10
Hov - måske lidt mere på validate:

function validateEan($ean) {
    $valid = preg_match("/^\d{13}$/", $ean);
    $valid = $valid && (substr($ean, 12) == getEanCheckDigit(substr($ean, 0, 12)))

    return $valid;
}
Avatar billede shooka Nybegynder
14. januar 2007 - 19:55 #11
Men hvordan kan algoritmen validere EAN-nummeret?
Avatar billede jensgram Nybegynder
14. januar 2007 - 19:56 #12
shooka > Den sammenligner 13. tegn med det beregnede check-tegn for de 12 første.
Avatar billede jensgram Nybegynder
14. januar 2007 - 19:57 #13
substr($ean, 12) == getEanCheckDigit(substr($ean, 0, 12))

|--- 13. tegn --|  |--- beregnet check via tegn 1-12 --|
Avatar billede straszek Praktikant
14. januar 2007 - 20:00 #14
Shooka > de se simpel ud, med outputtet af din kode e 6 - hvordan skal det forståes?
Avatar billede shooka Nybegynder
14. januar 2007 - 20:05 #15
Så er koden komplet:

<?php
$ean = "9101456790226";
$valean = ereg("^[0-9]{13}$", $ean);

if($valean)
{
$odd = ($ean[0]+$ean[2]+$ean[4]+$ean[6]+$ean[8]+$ean[10]+$ean[12])*3;
$even = $ean[1]+$ean[3]+$ean[5]+$ean[7]+$ean[9]+$ean[11];
$sum = $odd + $even;
$result = $sum/10;
$result2 = explode(".", $result);
$result3 = 10-$result2[1];

if ($result3 == $ean[12])
{
echo "EAN-nummeret: $ean er godkendt";
}
}

?>
Avatar billede shooka Nybegynder
14. januar 2007 - 20:06 #16
Det var fordi jeg ikke vidste, hvad man skulle validere resultatet med ;)
Avatar billede shooka Nybegynder
14. januar 2007 - 20:09 #17
Jens > Udregningen bruger da også 13. ciffer = $ean[12]

Tak for forklaringen, for det havde jeg da ikke helt forstået :)
Avatar billede jensgram Nybegynder
14. januar 2007 - 20:10 #18
shooka > Nej, du skal ikke have $ean[12] med - det er jo check-tegnet selv (det er vist mere rekursivitet end vi kan forsvare :).
Avatar billede jensgram Nybegynder
14. januar 2007 - 20:11 #19
13. tegn er check-tegnet. Det beregnes via "vægtet" sum af tegn 1-12.

Tror vi mener det samme, shooka, men taler lidt forbi hinanden.
Avatar billede shooka Nybegynder
14. januar 2007 - 20:17 #20
Avatar billede jensgram Nybegynder
14. januar 2007 - 20:24 #21
Under overskriften "EAN-13 (UCC-13)" gives der eksempel med 101742256780 - det giver check-tegn 5 - dvs. 1017422567805 er gyldigt!

Hvis jeg indtaster 101742256780 i formularen får jeg også 5. Ok?

Men - hvis jeg skriver 1017422567805 i formularen så fortæller den, at input skal være 12 tegn...

http://shooka.dk/eksperten_dk/spm755993/ean.php?ean=1017422567805 giver check 8. Hvorfor det?
Avatar billede jensgram Nybegynder
14. januar 2007 - 20:26 #22
Men! Jeg har også lavet en fejl.

function getEanCheckDigit($param) {
    $sum = 0;
    $odd = true;

    for ($i = 11; $i >= 0; $i--) {
        if ($odd) {
            $sum += 3 * intval(substr($param, $i, 1));
        } else {
            $sum += intval(substr($param, $i, 1));
        }
        $odd = !$odd;
    }

    check = 10 - (sum % 10);

    return ($check == 10 ? 0 : $check);
}
Avatar billede jensgram Nybegynder
14. januar 2007 - 20:27 #23
Nu går det godt :P

<?php

function getEanCheckDigit($param) {
    $sum = 0;
    $odd = true;

    for ($i = 11; $i >= 0; $i--) {
        if ($odd) {
            $sum += 3 * intval(substr($param, $i, 1));
        } else {
            $sum += intval(substr($param, $i, 1));
        }
        $odd = !$odd;
    }

    $check = 10 - ($sum % 10);

    return ($check == 10 ? 0 : $check);
}

function validateEan($ean) {
    $valid = preg_match("/^\d{13}$/", $ean);
    $valid = $valid && (substr($ean, 12) == getEanCheckDigit(substr($ean, 0, 12)));

    return $valid;
}

print getEanCheckDigit(101742256780);
var_dump(validateEan(1017422567805));

?>
Avatar billede shooka Nybegynder
14. januar 2007 - 20:27 #24
Det hedder kun EAN ikke EAN-13

Overskriften er EAN/UCC-14

Der er 13 tegn med

Det udskriver 8, fordi EAN-nummeret ikke er godkendt ;) På siden står også: (kun ens hvis EAN-nummeret er godkendt.)
Avatar billede jensgram Nybegynder
14. januar 2007 - 20:33 #25
UPS! Pinligt. Så har jeg kigget på den forkerte ;)

<?php

function getEanCheckDigit($param) {
    $sum = 0;
    $odd = true;

    for ($i = 12; $i >= 0; $i--) {
        $val  = intval(substr($param, $i, 1));
        $val *= ($odd ? 3 : 1);
        $odd = !$odd;

        $sum += $val;
    }

    $check = 10 - ($sum % 10);

    return ($check == 10 ? 0 : $check);
}

function validateEan($ean) {
    $valid = preg_match("/^\d{14}$/", $ean);
    $valid = $valid && (substr($ean, 13) == getEanCheckDigit(substr($ean, 0, 13)));

    return $valid;
}

print getEanCheckDigit(9101456790226);
var_dump(validateEan(91014567902266));

?>

Skulle gøre det ("EAN/UCC-14")

- Jens
Avatar billede shooka Nybegynder
14. januar 2007 - 20:36 #26
Det er da ikke pinligt... Jeg kunne heller ikke forstå det i starten :P
Avatar billede shooka Nybegynder
14. januar 2007 - 21:07 #27
Men hvilke oplysninger kommer din kode frem til?
Avatar billede shooka Nybegynder
14. januar 2007 - 21:10 #28
Det er hvad jeg kom frem til:

<?php
$ean = $_GET['ean'];
$valean = ereg("^[0-9]{13}$", $ean);

if($valean)
{
$odd = ($ean[0]+$ean[2]+$ean[4]+$ean[6]+$ean[8]+$ean[10]+$ean[12])*3;
$even = $ean[1]+$ean[3]+$ean[5]+$ean[7]+$ean[9]+$ean[11];
$sum = $odd + $even;
$result = $sum/10;
$result2 = explode(".", $result);
$result3 = 10-$result2[1];

if ($result3 == $ean[12])
{
echo "<strong>EAN-nummeret er godkendt.</strong>";
}
else
{
echo "<strong>EAN-nummeret er afvist.</strong>";
}

echo "<br />EAN-nummeret: <strong>".$ean."</strong><br />Sidste nummer fundet via udregningen: <strong>".$result3."</strong> (kun ens hvis EAN-nummeret er godkendt.)";
}
else
{
echo "<strong>EAN-nummeret er ikke af 13 tal!</strong>";
}

?>
Avatar billede straszek Praktikant
14. januar 2007 - 21:14 #29
shooka> Det ser fint ud men det virker bare ikke tag f.x. handelshøjskole i århus, deres ean nummer er 5790000288236 - og de kode siger det er et "EAN-nummeret er ikke af 13 tal!" - så det er et eller andet galt


Søren
Avatar billede shooka Nybegynder
14. januar 2007 - 21:16 #30
Det er af 13 tal, men den skriver det er afvist.
Avatar billede shooka Nybegynder
14. januar 2007 - 21:18 #31
Det skriver Jens' kode også... Det må være en forkert algoritme
Avatar billede straszek Praktikant
14. januar 2007 - 21:18 #32
ja, men det kan jo ikke passe da det er et rigtigt ean-nummer. har forøvrigt prøvet med 5 andre offentlige ean-numre med samme resultat
Avatar billede shooka Nybegynder
14. januar 2007 - 21:23 #33
Så må det være en amerikansk algoritme :S Ellers kan jeg ikke forklare det.
Avatar billede shooka Nybegynder
14. januar 2007 - 21:32 #34
Åhh nej, hvor er det bare pinligt. jeg har misforstået det... Det er EAN-13.

Det må du altså undskylde Jens.

Prøv nu Stras: http://shooka.dk/eksperten_dk/spm755993/ean.php?ean=5790000288236
Avatar billede straszek Praktikant
14. januar 2007 - 21:34 #35
Nemlig, ja og koden?
Avatar billede shooka Nybegynder
14. januar 2007 - 21:36 #36
Den kommer her:

<?php
$ean = $_GET['ean'];
$valean = ereg("^[0-9]{13}$", $ean);

if($valean)
{
$odd = ($ean[1]+$ean[3]+$ean[5]+$ean[7]+$ean[9]+$ean[11])*3;
$even = $ean[0]+$ean[2]+$ean[4]+$ean[6]+$ean[8]+$ean[10];
$sum = $odd + $even;
$result = $sum/10;
$result2 = explode(".", $result);
$result3 = 10-$result2[1];

if ($result3 == $ean[12])
{
echo "<strong>EAN-nummeret er godkendt.</strong>";
}
else
{
echo "<strong>EAN-nummeret er afvist.</strong>";
}

echo "<br />EAN-nummeret: <strong>".$ean."</strong><br />Sidste nummer fundet via udregningen: <strong>".$result3."</strong> (kun ens hvis EAN-nummeret er godkendt.)";
}
else
{
echo "<strong>EAN-nummeret er ikke af 13 tal!</strong>";
}
?>

Så skal $_GET['ean'] bare ændres til din variabel, som indeholder EAN-nummeret...
Avatar billede straszek Praktikant
14. januar 2007 - 21:39 #37
mange tak det virker glimrende - dem der vil have point kan smide nogle svar.

Endnu engang tak for hjælpen
Avatar billede shooka Nybegynder
14. januar 2007 - 21:43 #38
Her kommer et svar, og endnu en gang undskyld Jens
Avatar billede jensgram Nybegynder
14. januar 2007 - 21:54 #39
Hehe - det var da en forfærdelig masse misforståelser :)

Jeg tillader mig også at smide et svar ... og mit endelige forslag.


function getEan13CheckDigit($param) {
    $sum = 0;
    $odd = true;

    for ($i = 11; $i >= 0; $i--) {
        $val  = intval(substr($param, $i, 1));
        $val *= ($odd ? 3 : 1);
        $odd = !$odd;

        $sum += $val;
    }

    $check = 10 - ($sum % 10);

    return ($check == 10 ? 0 : $check);
}

function validateEan13($ean) {
    $valid = preg_match("/^\d{13}$/", $ean);
    $valid = $valid && (substr($ean, 12) == getEan13CheckDigit(substr($ean, 0, 12)));

    return $valid;
}

print getEan13CheckDigit(101742256780);
var_dump(validateEan13(1017422567805));
Avatar billede shooka Nybegynder
14. januar 2007 - 22:10 #40
Det skal der også være plads til :) Det var trods alt dig, som kom med det første rigtige svar :)
Avatar billede straszek Praktikant
06. februar 2007 - 19:00 #41
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Vi tilbyder markedets bedste kurser inden for webudvikling

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester