ISBN13 check digit: Difference between revisions

Content added Content deleted
(Added more general routine)
(Optimized routine beyond the specs of my original one)
Line 1,170: Line 1,170:


=={{header|Forth}}==
=={{header|Forth}}==
The following word not only identifies correct 13 digit ISBN (and EAN) codes, but also 8 digit EAN and GTIN codes.
<lang>: is-digit [char] 0 - 10 u< ;
<lang>: is-digit [char] 0 - 10 u< ;


: isbn? ( a n -- f)
: isbn? ( a n -- f)
1- 2dup chars + c@ [char] 0 - >r 2>r 0 1 2r> bounds ?do
1- chars over + 2>r 0 1 2r> ?do
dup i c@ dup is-digit
if [char] 0 - * rot + swap 3 * 8 mod else drop drop then
loop drop r> + 10 mod 0=
;</lang>
The following slightly modified word not only identifies correct 13 digit ISBN (and EAN) codes, but also 8 digit EAN and GTIN codes:
<lang>: isbn? ( a n -- f)
bounds 2>r 0 dup 2r@ ?do i c@ is-digit + loop abs 1- 1 and 2* 1+ 2r> ?do
dup i c@ dup is-digit \ get length and factor, setup loop
dup i c@ dup is-digit \ get length and factor, setup loop
if [char] 0 - * rot + swap 3 * 8 mod else drop drop then
if [char] 0 - * rot + swap 3 * 8 mod else drop drop then
loop drop 10 mod 0= \ now calculate checksum
-1 chars +loop drop 10 mod 0= \ now calculate checksum
;</lang>
;</lang>
{{out}}
{{out}}