ISBN13 check digit: Difference between revisions

m
 
(18 intermediate revisions by 7 users not shown)
Line 34:
R product % 10 == 0
 
V tests = |‘978-17343145020596528126
978-17343145090596528120
978-1788399081
978-1788399083’.split("\n")
Line 44:
{{out}}
<pre>
ISBN13 978-17343145020596528126 validates 1B
ISBN13 978-17343145090596528120 validates 0B
ISBN13 978-1788399081 validates 1B
ISBN13 978-1788399083 validates 0B
Line 122:
{{out}}
 
<pre>A>isbn13 978-17343145020596528126
good
A>isbn13 978-17343145090596528120
bad
A>isbn13 978-1788399081
Line 190:
{{out}}
 
<pre>C:\>isbn13 978-17343145020596528126
good
C:\>isbn13 978-17343145090596528120
bad
C:\>isbn13 978-1788399081
Line 199:
bad</pre>
 
=={{header|ABC}}==
<syntaxhighlight lang="abc">HOW TO REPORT valid.isbn13 str:
PUT {} IN digits
FOR d IN {0..9}: PUT d IN digits["`d`"]
IF #str <> 14 OR str item 4 <> '-': FAIL
PUT 1, 0 IN mul, sum
FOR c IN str|3 ^ str@5:
IF c not.in keys digits: FAIL
PUT sum + digits[c] * mul IN sum
PUT 4 - mul IN mul
REPORT sum mod 10 = 0
 
PUT {} IN tests
PUT "978-0596528126" IN tests[1]
PUT "978-0596528120" IN tests[2]
PUT "978-1788399081" IN tests[3]
PUT "978-1788399083" IN tests[4]
 
FOR test IN tests:
SELECT:
valid.isbn13 test: WRITE test^": good"/
ELSE: WRITE test^": bad"/</syntaxhighlight>
{{out}}
<pre>978-0596528126: good
978-0596528120: bad
978-1788399081: good
978-1788399083: bad</pre>
=={{header|Action!}}==
{{libheader|Action! Tool Kit}}
Line 241 ⟶ 268:
Put(125) PutE() ;clear screen
 
Test("978-17343145020596528126")
Test("978-17343145090596528120")
Test("978-1788399081")
Test("978-1788399083")
Line 249 ⟶ 276:
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/ISBN13_check_digit.png Screenshot from Atari 8-bit computer]
<pre>
978-17343145020596528126 is correct
978-17343145090596528120 is incorrect
978-1788399081 is correct
978-1788399083 is incorrect
Line 288 ⟶ 315:
end Show;
begin
Show ("978-17343145020596528126");
Show ("978-17343145090596528120");
Show ("978-1788399081");
Show ("978-1788399083");
end ISBN_Check;</syntaxhighlight>
{{out}}
<pre>978-17343145020596528126 Good
978-17343145090596528120 Bad
978-1788399081 Good
978-1788399083 Bad</pre>
Line 323 ⟶ 350:
END; # check isbn13 #
# task test cases #
[]STRING tests = ( "978-17343145020596528126", "978-17343145090596528120", "978-1788399081", "978-1788399083" );
[]BOOL expected = ( TRUE, FALSE, TRUE, FALSE );
FOR pos FROM LWB tests TO UPB tests DO
Line 338 ⟶ 365:
{{out}}
<pre>
978-17343145020596528126: good
978-17343145090596528120: bad
978-1788399081: good
978-1788399083: bad
Line 353 ⟶ 380:
{{out}}
 
<pre> check_isbn13¨ '978-17343145020596528126' '978-17343145090596528120' '978-1788399081' '978-1788399083'
1 0 1 0</pre>
 
Line 388 ⟶ 415:
end script
map(test, {"978-17343145020596528126", "978-17343145090596528120", ¬
"978-1788399081", "978-1788399083"})
end run
Line 565 ⟶ 592:
end zipWith</syntaxhighlight>
{{Out}}
<pre>{{"978-17343145020596528126", true}, {"978-17343145090596528120", false}, {"978-1788399081", true}, {"978-1788399083", false}}</pre>
 
===Straightforward===
Line 599 ⟶ 626:
set output to {}
set verdicts to {"bad", "good"}
repeat with thisISBN13 in {"978-17343145020596528126", "978-17343145090596528120", "978-1788399081", "978-1788399083"}
set isValid to validateISBN13(thisISBN13)
set end of output to thisISBN13 & ": " & item ((isValid as integer) + 1) of verdicts
Line 611 ⟶ 638:
 
{{output}}
<pre>"978-17343145020596528126: good
978-17343145090596528120: bad
978-1788399081: good
978-1788399083: bad"</pre>
Line 660 ⟶ 687:
 
tests: [
"978-17343145020596528126" "978-17343145090596528120"
"978-1788399081" "978-1788399083"
]
Line 670 ⟶ 697:
{{out}}
 
<pre>978-17343145020596528126 => true
978-17343145090596528120 => false
978-1788399081 => true
978-1788399083 => false</pre>
Line 682 ⟶ 709:
}</syntaxhighlight>
Examples:<syntaxhighlight lang="autohotkey">output := ""
nums := ["978-17343145020596528126","978-17343145090596528120","978-1788399081","978-1788399083"]
for i, n in nums
output .= ISBN13_check_digit(n) "`n"
Line 688 ⟶ 715:
return</syntaxhighlight>
{{out}}
<pre>978-17343145020596528126 (good)
978-17343145090596528120 (bad)
978-1788399081 (good)
978-1788399083 (bad)</pre>
Line 697 ⟶ 724:
# syntax: GAWK -f ISBN13_CHECK_DIGIT.AWK
BEGIN {
arr[++n] = "978-17343145020596528126"
arr[++n] = "978-17343145090596528120"
arr[++n] = "978-1788399081"
arr[++n] = "978-1788399083"
Line 720 ⟶ 747:
{{out}}
<pre>
978-17343145020596528126 OK
978-17343145090596528120 NG check digit S/B 2
978-1788399081 OK
978-1788399083 NG check digit S/B 1
Line 731 ⟶ 758:
{{trans|Ring}}
<syntaxhighlight lang="vb">arraybase 1
dim isbn = {"978-17343145020596528126", "978-17343145090596528120", "978-1788399081", "978-1788399083", "978-2-74839-908-0", "978-2-74839-908-5", "978 1 86197 876 9"}
 
for n = 1 to isbn[?]
Line 782 ⟶ 809:
 
let start() be
$( show("978-17343145020596528126")
show("978-17343145090596528120")
show("978-1788399081")
show("978-1788399083")
$)</syntaxhighlight>
{{out}}
<pre>978-17343145020596528126: good
978-17343145090596528120: bad
978-1788399081: good
978-1788399083: bad</pre>
Line 820 ⟶ 847:
int main() {
int i;
const char* isbns[] = {"978-17343145020596528126", "978-17343145090596528120", "978-1788399081", "978-1788399083"};
for (i = 0; i < 4; ++i) {
printf("%s: %s\n", isbns[i], check_isbn13(isbns[i]) ? "good" : "bad");
Line 829 ⟶ 856:
{{out}}
<pre>
978-17343145020596528126: good
978-17343145090596528120: bad
978-1788399081: good
978-1788399083: bad
Line 866 ⟶ 893:
 
int main() {
auto isbns = { "978-17343145020596528126", "978-17343145090596528120", "978-1788399081", "978-1788399083" };
for (auto isbn : isbns) {
std::cout << isbn << ": " << (check_isbn13(isbn) ? "good" : "bad") << '\n';
Line 874 ⟶ 901:
}</syntaxhighlight>
{{out}}
<pre>978-17343145020596528126: good
978-17343145090596528120: bad
978-1788399081: good
978-1788399083: bad</pre>
Line 886 ⟶ 913:
{
public static void Main() {
Console.WriteLine(CheckISBN13("978-17343145020596528126"));
Console.WriteLine(CheckISBN13("978-17343145090596528120"));
Console.WriteLine(CheckISBN13("978-1788399081"));
Console.WriteLine(CheckISBN13("978-1788399083"));
Line 931 ⟶ 958:
po: stream := stream$primary_output()
tests: array[string] := array[string]$
["978-17343145020596528126",
"978-17343145090596528120",
"978-1788399081",
"978-1788399083"]
Line 946 ⟶ 973:
end start_up</syntaxhighlight>
{{out}}
<pre>978-17343145020596528126: good
978-17343145090596528120: bad
978-1788399081: good
978-1788399083: bad</pre>
Line 980 ⟶ 1,007:
01 IX PIC S9(4) COMP.
01 TEST-ISBNS.
02 FILLER PIC X(14) VALUE '978-17343145020596528126'.
02 FILLER PIC X(14) VALUE '978-17343145090596528120'.
02 FILLER PIC X(14) VALUE '978-1788399081'.
02 FILLER PIC X(14) VALUE '978-1788399083'.
Line 1,096 ⟶ 1,123:
{{out}}
 
<pre>978-17343145020596528126 (good)
978-17343145090596528120 (bad)
978-1788399081 (good)
978-1788399083 (bad)
Line 1,129 ⟶ 1,156:
var isbns: [uint8][] := {
"978-17343145020596528126", "978-17343145090596528120", "978-1788399081", "978-1788399083"
};
Line 1,141 ⟶ 1,168:
end loop;</syntaxhighlight>
{{out}}
<pre>978-17343145020596528126: good
978-17343145090596528120: bad
978-1788399081: good
978-1788399083: bad</pre>
Line 1,168 ⟶ 1,195:
 
unittest {
assert(isValidISBN13("978-17343145020596528126"));
assert(!isValidISBN13("978-17343145090596528120"));
assert(isValidISBN13("978-1788399081"));
assert(!isValidISBN13("978-1788399083"));
Line 1,266 ⟶ 1,293:
 
proc nonrec main() void:
test("978-17343145020596528126");
test("978-17343145090596528120");
test("978-1788399081");
test("978-1788399083")
corp</syntaxhighlight>
{{out}}
<pre>978-17343145020596528126: good
978-17343145090596528120: bad
978-1788399081: good
978-1788399083: bad</pre>
Line 1,279 ⟶ 1,306:
=={{header|EasyLang}}==
<syntaxhighlight lang="text">
func ISBN13check ISBN$ . validisbn$ .
for ic$ =in 1strchars to len ISBNisbn$
currentChar$ = substrif ISBNc$ i<> 1"-"
if currentChar$ <> "-"ndigs += 1
digitCounter += 1
.
currentDigitdig = number currentCharc$
if digitCounterndigs mod 2 = 0
currentDigitdig *= 3
.
sum += currentDigitdig
.
if sum mod 10 =<> 0
valid$return = "true"0
else
valid$ = "false"
.
return 1
.
ISBNcodescodes$[] = [ "978-0596528126" "978-0596528120" "978-1788399081" "978-1788399083" ]
for ISBNcode$ in ISBNcodescodes$[]
callif ISBN13check ISBNcode$ valid$= 1
if valid print code$ =& "true is a valid ISBN"
print ISBN$ & " is a valid ISBN"
else
print ISBNcode$ & " is not a valid ISBN"
.
.
Line 1,393 ⟶ 1,417:
|-
| style="text-align:center; font-family:Arial, Helvetica, sans-serif !important; background-color:#000000; color:#ffffff" | 2
| 978-17343145020596528126
| style="background-color:#cbcefb" | TRUE
|-
| style="text-align:center; font-family:Arial, Helvetica, sans-serif !important; background-color:#000000; color:#ffffff" | 3
| 978-17343145090596528120
| FALSE
|-
Line 1,422 ⟶ 1,446:
{ [ length 13 = ] [ [ digit? ] all? ] [ (isbn13?) ] } 1&& ;
 
qw{ 978-17343145020596528126 978-17343145090596528120 978-1788399081 978-1788399083 }
[ dup isbn13? "good" "bad" ? "%s: %s\n" printf ] each</syntaxhighlight>
{{out}}
<pre>
978-17343145020596528126: good
978-17343145090596528120: bad
978-1788399081: good
978-1788399083: bad
Line 1,445 ⟶ 1,469:
In Forth, a "true" value is indicated by "-1".
<pre>
s" 978-17343145020596528126" isbn? . -1 ok
s" 978-17343145090596528120" isbn? . 0 ok
s" 978-1788399081" isbn? . -1 ok
s" 978-1788399083" isbn? . 0 ok
Line 1,456 ⟶ 1,480:
implicit none
 
character(len=14), dimension(4), parameter :: isbns=["978-17343145020596528126", "978-17343145090596528120", "978-1788399081", "978-1788399083"]
integer :: i
 
Line 1,493 ⟶ 1,517:
{{out}}
<pre>
978-17343145020596528126 : good
978-17343145090596528120 : bad
978-1788399081 : good
978-1788399083 : bad
Line 1,528 ⟶ 1,552:
end function
 
dim as string isbns(0 to 3) = { "978-17343145020596528126", "978-17343145090596528120", "978-1788399081", "978-1788399083" }
dim as uinteger i
for i = 0 to 3
Line 1,540 ⟶ 1,564:
{{out}}
<pre>
978-17343145020596528126: good
978-17343145090596528120: bad
978-1788399081: good
978-1788399083: bad
Line 1,568 ⟶ 1,592:
 
{{out}}
<pre>978-17343145020596528126 Valid ISBN13
978-17343145090596528120 Inalid ISBN13
978-1788399081 Valid ISBN13
978-1788399083 Inalid ISBN13</pre>
Line 1,575 ⟶ 1,599:
=={{header|Fōrmulæ}}==
 
{{FormulaeEntry|page=https://formulae.org/?script=examples/ISBN13_check_digit}}
Fōrmulæ programs are not textual, visualization/edition of programs is done showing/manipulating structures but not text. Moreover, there can be multiple visual representations of the same program. Even though it is possible to have textual representation &mdash;i.e. XML, JSON&mdash; they are intended for storage and transfer purposes more than visualization and edition.
 
'''Solution'''
Programs in Fōrmulæ are created/edited online in its [https://formulae.org website], However they run on execution servers. By default remote servers are used, but they are limited in memory and processing power, since they are intended for demonstration and casual use. A local server can be downloaded and installed, it has no limitations (it runs in your own computer). Because of that, example programs can be fully visualized and edited, but some of them will not run if they require a moderate or heavy computation/memory resources, and no local server is being used.
 
[[File:Fōrmulæ - ISBN13 check digit 01.png]]
In '''[https://formulae.org/?example=ISBN13_check_digit this]''' page you can see the program(s) related to this task and their results.
 
'''Test cases'''
 
[[File:Fōrmulæ - ISBN13 check digit 02.png]]
 
[[File:Fōrmulæ - ISBN13 check digit 03.png]]
 
=={{header|Gambas}}==
Line 1,585 ⟶ 1,615:
<syntaxhighlight lang="vbnet">Public Sub Main()
Dim isbn As String[] = ["978-17343145020596528126", "978-17343145090596528120", "978-1788399081", "978-1788399083", "978-2-74839-908-0", "978-2-74839-908-5", "978 1 86197 876 9"]
For n As Integer = 1 To isbn.Count
Line 1,642 ⟶ 1,672:
 
func main() {
isbns := []string{"978-17343145020596528126", "978-17343145090596528120", "978-1788399081", "978-1788399083"}
for _, isbn := range isbns {
res := "bad"
Line 1,654 ⟶ 1,684:
{{out}}
<pre>
978-17343145020596528126: good
978-17343145090596528120: bad
978-1788399081: good
978-1788399083: bad
Line 1,684 ⟶ 1,714:
mapM_
(printf "%s: Valid: %s\n" <*> (show . validIsbn13))
[ "978-17343145020596528126",
"978-17343145090596528120",
"978-1788399081",
"978-1788399083"
]</syntaxhighlight>
{{out}}
<pre>978-17343145020596528126: Valid: True
978-17343145090596528120: Valid: False
978-1788399081: Valid: True
978-1788399083: Valid: False</pre>
Line 1,712 ⟶ 1,742:
mapM_
(print . ((,) <*> isISBN13))
[ "978-17343145020596528126",
"978-17343145090596528120",
"978-1788399081",
"978-1788399083"
]</syntaxhighlight>
{{Out}}
<pre>("978-17343145020596528126",True)
("978-17343145090596528120",False)
("978-1788399081",True)
("978-1788399083",False)</pre>
Line 1,761 ⟶ 1,791:
{{out}}
 
<syntaxhighlight lang="j"> isbn13c;._1 ' 978-17343145020596528126 978-17343145090596528120 978-1788399081 978-1788399083'
1 0 1 0</syntaxhighlight>
 
Line 1,814 ⟶ 1,844:
An alternate demonstration
<syntaxhighlight lang="java">public static void main(){
System.out.println(isISBN13("978-17343145020596528126"));
System.out.println(isISBN13("978-17343145090596528120"));
System.out.println(isISBN13("978-1788399081"));
System.out.println(isISBN13("978-1788399083"));
Line 1,853 ⟶ 1,883:
 
def testingcodes:
["978-17343145020596528126", "978-17343145090596528120",
"978-1788399081", "978-1788399083"];
Line 1,861 ⟶ 1,891:
{{out}}
<pre>
978-17343145020596528126: good
978-17343145090596528120: bad
978-1788399081: good
978-1788399083: bad
Line 1,873 ⟶ 1,903:
end
 
const testingcodes = ["978-17343145020596528126", "978-17343145090596528120",
"978-1788399081", "978-1788399083"]
 
Line 1,881 ⟶ 1,911:
</syntaxhighlight>{{out}}
<pre>
978-17343145020596528126: good
978-17343145090596528120: bad
978-1788399081: good
978-1788399083: bad
Line 1,915 ⟶ 1,945:
describe("ISBN Utilities") {
mapOf(
"978-17343145020596528126" to true,
"978-17343145090596528120" to false,
"978-1788399081" to true,
"978-1788399083" to false
Line 1,932 ⟶ 1,962:
{{out}}
<pre>
978-17343145020596528126: good
978-17343145090596528120: bad
978-1788399081: good
978-1788399083: bad
Line 1,939 ⟶ 1,969:
 
=={{header|langur}}==
{{works with|langur|0.8.11}}
In this example, we map to multiple functions (actually 1 no-op).
<syntaxhighlight lang="langur">val .isbn13checkdigit = ffn(var .s) {
.s = replace(.s, RE/[\- ]/)
matching(.s -> re/^[0-9]{13}$/, .s) and
fold(ffn{+}, map [_, ffn{x *3}], s2n .s) div 10
}
 
val .tests = h{
"978-0596528126": true,
"978-0596528120": false,
"978-1788399081": true,
"978-1788399083": false,
}
 
for .key of .tests {
val .pass = .isbn13checkdigit(.key)
write .key, ": ", if(.pass: "good"; "bad")
writeln if(.pass == .tests[.key]: ""; " (ISBN-13 CHECK DIGIT TEST FAILED)")
}</syntaxhighlight>
 
{{works with|langur|0.9.0}}
In this example, we set a for loop value as it progresses.
<syntaxhighlight lang="langur">val .isbn13checkdigit = f(var .s) {
.s = replace(.s, RE/[\- ]/)
var .alt = true
matching(re/^[0-9]{13}$/, .s) and
for[=0] .d in s2n(.s) { _for += if(not= .alt: .d x 3; .d) } div 10
}
 
val .tests = h{
"978-0596528126": true,
"978-0596528120": false,
Line 2,024 ⟶ 2,031:
 
function main()
test("978-17343145020596528126")
test("978-17343145090596528120")
test("978-1788399081")
test("978-1788399083")
Line 2,032 ⟶ 2,039:
main()</syntaxhighlight>
{{out}}
<pre>978-17343145020596528126: good
978-17343145090596528120: bad
978-1788399081: good
978-1788399083: bad</pre>
Line 2,050 ⟶ 2,057:
]
]
ValidISBNQ["978-17343145020596528126"]
ValidISBNQ["978-17343145090596528120"]
ValidISBNQ["978-1788399081"]
ValidISBNQ["978-1788399083"]</syntaxhighlight>
Line 2,060 ⟶ 2,067:
False</pre>
 
=={{header|MiniScript}}==
This GUI implementation is for use with [http://miniscript.org/MiniMicro Mini Micro].
<syntaxhighlight lang="miniscript">
isISBN13 = function(n)
n = n.replace("-","").replace(" ","")
s = 0
for i in range(0, n.len-1,2)
s += n[i].val
end for
for i in range(1, n.len-1,2)
s += n[i].val * 3
end for
return not (s % 10)
end function
 
testValues = "978-0596528126 978-0596528120 978-1788399081 978-1788399083".split(" ")
for val in testValues
print val + " " + ["bad", "good"][isISBN13(val)]
end for
</syntaxhighlight>
{{out}}
<pre>
978-0596528126 good
978-0596528120 bad
978-1788399081 good
978-1788399083 bad</pre>
 
=={{header|Miranda}}==
<syntaxhighlight lang="miranda">main :: [sys_message]
main = [Stdout (lay (map test tests))]
 
test :: [char]->[char]
test isbn = isbn ++ ": good", if isbn13 isbn
= isbn ++ ": bad", otherwise
 
tests :: [[char]]
tests = ["978-0596528126",
"978-0596528120",
"978-1788399081",
"978-1788399083"]
 
isbn13 :: [char]->bool
isbn13 str = False, if #isbn ~= 13 \/ ~and (map digit isbn)
= check mod 10 = 0, otherwise
where isbn = filter (~= '-') str
digits = map (numval.(:[])) isbn
check = sum (zipwith (*) digits (concat (repeat [1,3])))
 
uncurry :: (*->**->***)->(*,**)->***
uncurry f (a,b) = f a b
 
zipwith :: (*->**->***)->[*]->[**]->[***]
zipwith f a b = map (uncurry f) (zip2 a b)</syntaxhighlight>
{{out}}
<pre>978-0596528126: good
978-0596528120: bad
978-1788399081: good
978-1788399083: bad</pre>
 
=={{header|Modula-2}}==
Line 2,101 ⟶ 2,166:
 
BEGIN
check('978-17343145020596528126');
check('978-17343145090596528120');
check('978-1788399081');
check('978-1788399083');
END ISBN.</syntaxhighlight>
{{out}}
<pre>978-17343145020596528126: good
978-17343145090596528120: bad
978-1788399081: good
978-1788399083: bad</pre>
Line 2,141 ⟶ 2,206:
end
 
isbns = {"978-17343145020596528126", "978-17343145090596528120", "978-1788399081", "978-1788399083"}
for isbn in isbns
res = "bad"
Line 2,151 ⟶ 2,216:
end</syntaxhighlight>
{{out}}
<pre>978-17343145020596528126: good
978-17343145090596528120: bad
978-1788399081: good
978-1788399083: bad</pre>
Line 2,170 ⟶ 2,235:
 
when is_main_module:
let isbns = [ "978-17343145020596528126", "978-17343145090596528120",
"978-1788399081", "978-1788399083" ]
for isbn in isbns:
Line 2,177 ⟶ 2,242:
{{out}}
<pre>
978-17343145020596528126: good
978-17343145090596528120: bad
978-1788399081: good
978-1788399083: bad
Line 2,265 ⟶ 2,330:
{ === MAIN ============================================================= }
begin
writeLn(isValidISBNString('978-17343145020596528126'));
writeLn(isValidISBNString('978-17343145090596528120'));
writeLn(isValidISBNString('978-1788399081'));
writeLn(isValidISBNString('978-1788399083'))
Line 2,287 ⟶ 2,352:
}
 
for (<978-17343145020596528126 978-17343145090596528120 978-1788399081 978-1788399083 978-2-74839-908-0 978-2-74839-908-5>) {
my($isbn,$check) = /(.*)(.)/;
my $check_d = check_digit($isbn);
Line 2,293 ⟶ 2,358:
}</syntaxhighlight>
{{out}}
<pre>978-17343145020596528126 : Good
978-17343145090596528120 : Bad check-digit 9; should be 2
978-1788399081 : Good
978-1788399083 : Bad check-digit 3; should be 1
Line 2,320 ⟶ 2,385:
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">isbns</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #008000;">"978-17343145020596528126"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"978-17343145090596528120"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"978-1788399081"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"978-1788399083"</span><span style="color: #0000FF;">,</span>
<span style="color: #008000;">"978-2-74839-908-0"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"978-2-74839-908-5"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"978 1 86197 876 9"</span><span style="color: #0000FF;">}</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">isbns</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span> <span style="color: #000000;">check_isbn13</span><span style="color: #0000FF;">(</span><span style="color: #000000;">isbns</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">])</span> <span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
Line 2,326 ⟶ 2,391:
{{out}}
<pre>
978-17343145020596528126: good
978-17343145090596528120: bad
978-1788399081: good
978-1788399083: bad
Line 2,351 ⟶ 2,416:
(if (isbn13? A) 'ok 'fail) ) )
(quote
"978-17343145020596528126"
"978-17343145090596528120"
"978-1-86197-876-9"
"978-2-74839-908-5"
Line 2,358 ⟶ 2,423:
{{out}}
<pre>
978-17343145020596528126 ok
978-17343145090596528120 fail
978-1-86197-876-9 ok
978-2-74839-908-5 fail
Line 2,401 ⟶ 2,466:
/* TESTS */
DECLARE TEST (4) ADDRESS;
TEST(0) = .'978-17343145020596528126$';
TEST(1) = .'978-17343145090596528120$';
TEST(2) = .'978-1788399081$';
TEST(3) = .'978-1788399083$';
Line 2,420 ⟶ 2,485:
EOF</syntaxhighlight>
{{out}}
<pre>978-17343145020596528126: GOOD
978-17343145090596528120: BAD
978-1788399081: GOOD
978-1788399083: BAD</pre>
Line 2,429 ⟶ 2,494:
function Get-ISBN13 {
$codes = (
"978-17343145020596528126",
"978-17343145090596528120",
"978-1788399081",
"978-1788399083"
Line 2,469 ⟶ 2,534:
{{out}}
<pre>
978-17343145020596528126 Good
978-17343145090596528120 Bad
978-1788399081 Good
978-1788399083 Bad
Line 2,491 ⟶ 2,556:
 
If OpenConsole()
TestISBN13("978-17343145020596528126")
TestISBN13("978-17343145090596528120")
TestISBN13("978-1788399081")
TestISBN13("978-1788399083")
Line 2,498 ⟶ 2,563:
EndIf</syntaxhighlight>
{{out}}
<pre>978-17343145020596528126 good
978-17343145090596528120 bad
978-1788399081 good
978-1788399083 bad
Line 2,515 ⟶ 2,580:
if __name__ == '__main__':
tests = '''
978-17343145020596528126
978-17343145090596528120
978-1788399081
978-1788399083'''.strip().split()
Line 2,523 ⟶ 2,588:
 
{{out}}
<pre>ISBN13 978-17343145020596528126 validates True
ISBN13 978-17343145090596528120 validates False
ISBN13 978-1788399081 validates True
ISBN13 978-1788399083 validates False</pre>
Line 2,560 ⟶ 2,625:
print('\n'.join(
repr((s, isISBN13(s))) for s
in ["978-17343145020596528126",
"978-17343145090596528120",
"978-1788399081",
"978-1788399083"
Line 2,573 ⟶ 2,638:
</syntaxhighlight>
{{Out}}
<pre>('978-17343145020596528126', True)
('978-17343145090596528120', False)
('978-1788399081', True)
('978-1788399083', False)</pre>
Line 2,607 ⟶ 2,672:
else [ say "Bad" ] cr ] is isbn-test ( $ --> )
 
$ '978-17343145020596528126' isbn-test
$ '978-17343145090596528120' isbn-test
$ '978-1788399081' isbn-test
$ '978-1788399083' isbn-test</syntaxhighlight>
{{out}}
<pre>
978-17343145020596528126: Good
978-17343145090596528120: Bad
978-1788399081: Good
978-1788399083: Bad
Line 2,632 ⟶ 2,697:
(module+ test
(require rackunit)
(check-true (isbn13-check-digit-valid? "978-17343145020596528126"))
(check-false (isbn13-check-digit-valid? "978-17343145090596528120"))
(check-true (isbn13-check-digit-valid? "978-1788399081"))
(check-false (isbn13-check-digit-valid? "978-1788399083")))</syntaxhighlight>
Line 2,656 ⟶ 2,721:
"Bad check-digit $check; should be $check-digit"
} for words <
978-17343145020596528126
978-17343145090596528120
978-1788399081
978-1788399083
Line 2,664 ⟶ 2,729:
>;</syntaxhighlight>
{{out}}
<pre>978-17343145020596528126 : Good
978-17343145090596528120 : Bad check-digit 9; should be 2
978-1788399081 : Good
978-1788399083 : Bad check-digit 3; should be 1
Line 2,692 ⟶ 2,757:
 
; check given examples
foreach [str] ["978-17343145020596528126" "978-17343145090596528120" "978-1788399081" "978-1788399083"] [
prin str
prin " - "
Line 2,701 ⟶ 2,766:
{{out}}
<pre>
978-17343145020596528126 - true
978-17343145090596528120 - false
978-1788399081 - true
978-1788399083 - false
</pre>
 
=={{header|Refal}}==
<syntaxhighlight lang="refal">$ENTRY Go {
= <Test '978-0596528126'>
<Test '978-0596528120'>
<Test '978-1788399081'>
<Test '978-1788399083'>
};
 
Test {
e.X = <Prout e.X ': ' <ISBN e.X>>;
};
 
ISBN {
e.X, <Remove '-' e.X>: e.DS,
<CheckDigits e.DS>: {
False = Bad;
True = <ISBN1 e.DS>;
};
};
 
ISBN1 {
(13 s.Sum), <Mod s.Sum 10>: 0 = Good;
(13 s.Sum) e.X = Bad;
(s.N s.Sum) = Bad;
 
(s.N s.Sum) s.D e.X,
<+ s.N 1>: s.N1,
<Numb s.D>: s.V,
<Mod s.N 2>: {
0 = <ISBN1 (s.N1 <+ s.Sum s.V>) e.X>;
1 = <ISBN1 (s.N1 <+ s.Sum <* 3 s.V>>) e.X>;
};
 
e.X = <ISBN1 (0 0) e.X>;
};
 
Remove {
s.1 = ;
s.1 s.1 e.X = <Remove s.1 e.X>;
s.1 s.2 e.X = s.2 <Remove s.1 e.X>;
};
 
CheckDigits {
= True;
s.D e.X, '0123456789': e.A s.D e.B = <CheckDigits e.X>;
e.X = False;
};</syntaxhighlight>
{{out}}
<pre>978-0596528126: Good
978-0596528120: Bad
978-1788399081: Good
978-1788399083: Bad</pre>
 
=={{header|REXX}}==
Line 2,711 ⟶ 2,829:
<syntaxhighlight lang="rexx">/*REXX pgm validates the check digit of an ISBN─13 code (it may have embedded minuses).*/
parse arg $ /*obtain optional arguments from the CL*/
if $='' | if $="," then $= '978-17343145020596528126 978-17343145090596528120 978-1788399081 978-1788399083'
@ISBN= "ISBN─13 code isn't" /*a literal used when displaying msgs. */
/* [↓] remove all minuses from X code.*/
Line 2,740 ⟶ 2,858:
load "stdlib.ring"
 
isbn = ["978-17343145020596528126","978-17343145090596528120", "978-1788399081", "978-1788399083","978-2-74839-908-0","978-2-74839-908-5","978 1 86197 876 9"]
 
for n = 1 to len(isbn)
Line 2,765 ⟶ 2,883:
Output:
<pre>
978-17343145020596528126: true
978-17343145090596528120: bad
978-1788399081: true
978-1788399083: bad
Line 2,807 ⟶ 2,925:
end
 
isbns = ["978-17343145020596528126", "978-17343145090596528120", "978-1788399081", "978-1788399083"]
isbns.each{|isbn| puts "#{isbn}: #{validISBN13?(isbn)}" }
</syntaxhighlight>{{out}}
<pre>978-17343145020596528126: true
978-17343145090596528120: false
978-1788399081: true
978-1788399083: false
Line 2,818 ⟶ 2,936:
=={{header|Rust}}==
<syntaxhighlight lang="rust">fn main() {
let isbns = ["978-17343145020596528126", "978-17343145090596528120", "978-1788399081", "978-1788399083"];
isbns.iter().for_each(|isbn| println!("{}: {}", isbn, check_isbn(isbn)));
}
Line 2,834 ⟶ 2,952:
{{out}}
<pre>
978-17343145020596528126: true
978-17343145090596528120: false
978-1788399081: true
978-1788399083: false
Line 2,871 ⟶ 2,989:
var string: str is "";
begin
for str range [] ("978-17343145020596528126", "978-17343145090596528120", "978-1788399081", "978-1788399083") do
writeln(str <& ": " <& isISBN13(str));
end for;
Line 2,877 ⟶ 2,995:
{{out}}
<pre>
978-17343145020596528126: TRUE
978-17343145090596528120: FALSE
978-1788399081: TRUE
978-1788399083: FALSE
</pre>
=={{header|SETL}}==
<syntaxhighlight lang="setl">program isbn13;
loop for test in [
"978-0596528126", "978-0596528120",
"978-1788399081", "978-1788399083"
] do
print(test + if valid_isbn13 test then ": good" else ": bad" end);
end loop;
 
op valid_isbn13(isbn);
if #isbn /= 14
or isbn(4) /= '-'
or exists c in isbn | not c in "0123456789-" then
return false;
end if;
 
m := 3;
loop for ch in isbn | ch in "0123456789" do
s +:= val ch * (m := 4 - m);
end loop;
return s mod 10 = 0;
end op;
end program;</syntaxhighlight>
{{out}}
<pre>978-0596528126: good
978-0596528120: bad
978-1788399081: good
978-1788399083: bad</pre>
 
=={{header|Standard ML}}==
===Easy to read version===
<syntaxhighlight lang="sml">local
<syntaxhighlight lang="sml">(* these type decorations are optional, you could just as well put:
fun isValidISBN s =
*)
fun isValidISBN (s : string) : bool =
let
val digits = List.filter Char.isDigit (explode s)
val nums = map (fn x => ord x - ord #"0") digits
val len = length nums
fun sumISBN [] = raise Domain
| sumISBN [x] = x
| sumISBN (x1::x2::xs) = x1 + 3*x2 + sumISBN xs
in
len = 13 andalso sumISBN nums mod 10 = 0
end
 
val test = ["978-1734314502", "978-1734314509",
"978-1788399081", "978-1788399083"]
 
fun printTest (s : string) : unit =
(print s; print (if isValidISBN s then ": good\n" else ": bad\n"))
 
fun main () = app printTest test</syntaxhighlight>
 
===Original version===
<syntaxhighlight lang="sml">let
fun check (c, p as (m, n)) =
if Char.isDigit c then
Line 2,895 ⟶ 3,066:
end
 
val test = ["978-17343145020596528126", "978-17343145090596528120", "978-1788399081", "978-1788399083"]
val () = (print
o concat
o map (fn s => s ^ (if checkISBN s then ": good\n" else ": bad\n"))) test</syntaxhighlight>
{{out}}
<pre>978-17343145020596528126: good
978-17343145090596528120: bad
978-1788399081: good
978-1788399083: bad</pre>
Line 2,922 ⟶ 3,093:
 
let cases = [
"978-17343145020596528126",
"978-17343145090596528120",
"978-1788399081",
"978-1788399083"
Line 2,935 ⟶ 3,106:
{{out}}
 
<pre>978-17343145020596528126 => good
978-17343145090596528120 => bad
978-1788399081 => good
978-1788399083 => bad</pre>
Line 2,957 ⟶ 3,128:
}
foreach test {
978-17343145020596528126
978-17343145090596528120
978-1788399081
978-1788399083
Line 2,964 ⟶ 3,135:
</syntaxhighlight>
{{out}}
<pre>978-17343145020596528126:true
978-17343145090596528120:false
978-1788399081:true
978-1788399083:false</pre>
Line 2,986 ⟶ 3,157:
=={{header|uBasic/4tH}}==
{{works with|version 3.64.0}}
<syntaxhighlight lang="text">a := "978-17343145020596528126"
Print Show(a), Show (Iif (Func(_IsISBN (a)), "good", "bad"))
 
a := "978-17343145090596528120"
Print Show(a), Show (Iif (Func(_IsISBN (a)), "good", "bad"))
 
Line 3,014 ⟶ 3,185:
Return ((c@ % 10) = 0) ' modulus 10 must be zero</syntaxhighlight>
{{out}}
<pre>978-17343145020596528126 good
978-17343145090596528120 bad
978-1788399081 good
978-1788399083 bad
Line 3,033 ⟶ 3,204:
}
 
for isbn in 978-17343145020596528126 978-17343145090596528120 978-1788399081 978-1788399083; do
printf '%s: ' "$isbn"
if check_isbn13 "$isbn"; then
Line 3,042 ⟶ 3,213:
done</syntaxhighlight>
{{Out}}
<pre>978-17343145020596528126: OK
978-17343145090596528120: NOT OK
978-1788399081: OK
978-1788399083: NOT OK</pre>
Line 3,070 ⟶ 3,241:
 
Sub Main()
Console.WriteLine(CheckISBN13("978-17343145020596528126"))
Console.WriteLine(CheckISBN13("978-17343145090596528120"))
Console.WriteLine(CheckISBN13("978-1788399081"))
Console.WriteLine(CheckISBN13("978-1788399083"))
Line 3,110 ⟶ 3,281:
fn main() {
isbns := ["978-17343145020596528126", "978-17343145090596528120", "978-1788399081", "978-1788399083"]
for isbn in isbns {
mut res := "bad"
Line 3,122 ⟶ 3,293:
{{out}}
<pre>
978-17343145020596528126: good
978-17343145090596528120: bad
978-1788399081: good
978-1788399083: bad
Line 3,129 ⟶ 3,300:
 
=={{header|Wren}}==
<syntaxhighlight lang="ecmascriptwren">var isbn13 = Fn.new { |s|
var cps = s.codePoints
var digits = []
Line 3,146 ⟶ 3,317:
}
 
var tests = ["978-17343145020596528126", "978-17343145090596528120", "978-1788399081", "978-1788399083"]
for (test in tests) {
System.print("%(test) -> %(isbn13.call(test) ? "good" : "bad")")
Line 3,153 ⟶ 3,324:
{{out}}
<pre>
978-17343145020596528126 -> good
978-17343145090596528120 -> bad
978-1788399081 -> good
978-1788399083 -> bad
Line 3,180 ⟶ 3,351:
];
 
[ISBN13("978-17343145020596528126");
ISBN13("978-17343145090596528120");
ISBN13("978-1788399081");
ISBN13("978-1788399083");
Line 3,190 ⟶ 3,361:
{{out}}
<pre>
978-17343145020596528126: good
978-17343145090596528120: bad
978-1788399081: good
978-1788399083: bad
Line 3,199 ⟶ 3,370:
 
=={{header|zkl}}==
<syntaxhighlight lang="zkl">fcn ISBN13_check(isbn){ // "978-17343145020596528126", throws on invalid digits
var [const] one3=("13"*6 + 1).split("").apply("toInt"); // examine 13 digits
// one3=("13"*6) if you want to calculate what the check digit should be
Line 3,206 ⟶ 3,377:
<syntaxhighlight lang="zkl">isbns:=
#<<<"
978-17343145020596528126
978-17343145090596528120
978-1788399081
978-1788399083
Line 3,217 ⟶ 3,388:
{{out}}
<pre>
978-17343145020596528126 Good
978-17343145090596528120 Bad
978-1788399081 Good
978-1788399083 Bad
885

edits