Jesper,
I don't know if these UPC codes can have variable length. But if they
can, your algorithm should be reversed. That is, the rightmost digit is
the first digit (the odd digit).
Note that there are four important differences between the UPC mod10
algorithm and the traditional Luhn mod10 algorithm:
1. Odd and Even digits are reversed (Luhn doubles each even digit,
UPC triples each odd digit)
2. UPC does not add individual digits from the result of step 1,
instead, it merely add the result
3. UPC triples, where Luhn doubles digits
4. UPC adds a checksum at the rightmost position, which should not
be taken into the calculation itself
I believe from looking at your code that 2, 3 and 4 are considered in
your code, but 1 is not (esp. not calculated from the right).
Here's a Luhn's algorithm in a single XPath (tested):
sum(for $j in
(for $i in reverse(string-to-codepoints(.))[position() mod 2 =
0] return ($i - 48) * 2,
for $i in reverse(string-to-codepoints(.))[position() mod 2 = 1]
return ($i - 48))
return ($j mod 10, $j idiv 10))
Here's UPC's algorithm, based on the above, in a single XPath (*not*
tested by lack of testing material and specs):
sum(
for $i in reverse(string-to-codepoints(substring(., 1,
string-length(.) - 1))[position() mod 2 = 1] return ($i - 48) * 3,
for $i in reverse(string-to-codepoints(substring(., 1,
string-length(.) - 1)))[position() mod 2 = 10 return ($i - 48))
= number(substring(., string-length(.) - 1, 1))
You could consider to put the repeated logic inside a variable, in which
case the expression becomes easier:
<xsl:variable name="x" select="for $i in
reverse(string-to-codepoints(substring(., 1, string-length(.) - 1))
return $i - 48" />
the XPath then becomes:
sum(
for $i in $x[position() mod 2 = 1] return $i * 3,
for $i in $x[position() mod 2 = 0] return $i,
= number(substring(., string-length(.) - 1, 1))
Cheers,
-- Abel Braaksma
Jesper Tverskov wrote:
On 5/24/07, Abel Braaksma <abel.online@xxxxxxxxx> wrote:
Is yours the same as describe here
http://en.wikipedia.org/wiki/Luhn_algorithm ? Because it seems to me
that your code does not equal that description.
I have until now used this one:
http://www.idautomation.com/upceanfaq.html
I have a feeling that I must look into exactly what bar codes are used
these days, before I continue.
Jesper