ISBN13 check digit: Difference between revisions

m
 
(15 intermediate revisions by 6 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">
procfunc ISBN13check ISBNisbn$ . valid .
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
validreturn = 10
else
valid = 0
.
return 1
.
ISBNcodescodes$[] = [ "978-0596528126" "978-0596528120" "978-1788399081" "978-1788399083" ]
for ISBNcode$ in ISBNcodescodes$[]
callif ISBN13check ISBNcode$ valid= 1
print code$ & " is a valid ISBN"
if valid = 1
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,591 ⟶ 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,648 ⟶ 1,672:
 
func main() {
isbns := []string{"978-17343145020596528126", "978-17343145090596528120", "978-1788399081", "978-1788399083"}
for _, isbn := range isbns {
res := "bad"
Line 1,660 ⟶ 1,684:
{{out}}
<pre>
978-17343145020596528126: good
978-17343145090596528120: bad
978-1788399081: good
978-1788399083: bad
Line 1,690 ⟶ 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,718 ⟶ 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,767 ⟶ 1,791:
{{out}}
 
<syntaxhighlight lang="j"> isbn13c;._1 ' 978-17343145020596528126 978-17343145090596528120 978-1788399081 978-1788399083'
1 0 1 0</syntaxhighlight>
 
Line 1,820 ⟶ 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,859 ⟶ 1,883:
 
def testingcodes:
["978-17343145020596528126", "978-17343145090596528120",
"978-1788399081", "978-1788399083"];
Line 1,867 ⟶ 1,891:
{{out}}
<pre>
978-17343145020596528126: good
978-17343145090596528120: bad
978-1788399081: good
978-1788399083: bad
Line 1,879 ⟶ 1,903:
end
 
const testingcodes = ["978-17343145020596528126", "978-17343145090596528120",
"978-1788399081", "978-1788399083"]
 
Line 1,887 ⟶ 1,911:
</syntaxhighlight>{{out}}
<pre>
978-17343145020596528126: good
978-17343145090596528120: bad
978-1788399081: good
978-1788399083: bad
Line 1,921 ⟶ 1,945:
describe("ISBN Utilities") {
mapOf(
"978-17343145020596528126" to true,
"978-17343145090596528120" to false,
"978-1788399081" to true,
"978-1788399083" to false
Line 1,938 ⟶ 1,962:
{{out}}
<pre>
978-17343145020596528126: good
978-17343145090596528120: bad
978-1788399081: good
978-1788399083: bad
Line 1,945 ⟶ 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,030 ⟶ 2,031:
 
function main()
test("978-17343145020596528126")
test("978-17343145090596528120")
test("978-1788399081")
test("978-1788399083")
Line 2,038 ⟶ 2,039:
main()</syntaxhighlight>
{{out}}
<pre>978-17343145020596528126: good
978-17343145090596528120: bad
978-1788399081: good
978-1788399083: bad</pre>
Line 2,056 ⟶ 2,057:
]
]
ValidISBNQ["978-17343145020596528126"]
ValidISBNQ["978-17343145090596528120"]
ValidISBNQ["978-1788399081"]
ValidISBNQ["978-1788399083"]</syntaxhighlight>
Line 2,066 ⟶ 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,107 ⟶ 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,147 ⟶ 2,206:
end
 
isbns = {"978-17343145020596528126", "978-17343145090596528120", "978-1788399081", "978-1788399083"}
for isbn in isbns
res = "bad"
Line 2,157 ⟶ 2,216:
end</syntaxhighlight>
{{out}}
<pre>978-17343145020596528126: good
978-17343145090596528120: bad
978-1788399081: good
978-1788399083: bad</pre>
Line 2,176 ⟶ 2,235:
 
when is_main_module:
let isbns = [ "978-17343145020596528126", "978-17343145090596528120",
"978-1788399081", "978-1788399083" ]
for isbn in isbns:
Line 2,183 ⟶ 2,242:
{{out}}
<pre>
978-17343145020596528126: good
978-17343145090596528120: bad
978-1788399081: good
978-1788399083: bad
Line 2,271 ⟶ 2,330:
{ === MAIN ============================================================= }
begin
writeLn(isValidISBNString('978-17343145020596528126'));
writeLn(isValidISBNString('978-17343145090596528120'));
writeLn(isValidISBNString('978-1788399081'));
writeLn(isValidISBNString('978-1788399083'))
Line 2,293 ⟶ 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,299 ⟶ 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,326 ⟶ 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,332 ⟶ 2,391:
{{out}}
<pre>
978-17343145020596528126: good
978-17343145090596528120: bad
978-1788399081: good
978-1788399083: bad
Line 2,357 ⟶ 2,416:
(if (isbn13? A) 'ok 'fail) ) )
(quote
"978-17343145020596528126"
"978-17343145090596528120"
"978-1-86197-876-9"
"978-2-74839-908-5"
Line 2,364 ⟶ 2,423:
{{out}}
<pre>
978-17343145020596528126 ok
978-17343145090596528120 fail
978-1-86197-876-9 ok
978-2-74839-908-5 fail
Line 2,407 ⟶ 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,426 ⟶ 2,485:
EOF</syntaxhighlight>
{{out}}
<pre>978-17343145020596528126: GOOD
978-17343145090596528120: BAD
978-1788399081: GOOD
978-1788399083: BAD</pre>
Line 2,435 ⟶ 2,494:
function Get-ISBN13 {
$codes = (
"978-17343145020596528126",
"978-17343145090596528120",
"978-1788399081",
"978-1788399083"
Line 2,475 ⟶ 2,534:
{{out}}
<pre>
978-17343145020596528126 Good
978-17343145090596528120 Bad
978-1788399081 Good
978-1788399083 Bad
Line 2,497 ⟶ 2,556:
 
If OpenConsole()
TestISBN13("978-17343145020596528126")
TestISBN13("978-17343145090596528120")
TestISBN13("978-1788399081")
TestISBN13("978-1788399083")
Line 2,504 ⟶ 2,563:
EndIf</syntaxhighlight>
{{out}}
<pre>978-17343145020596528126 good
978-17343145090596528120 bad
978-1788399081 good
978-1788399083 bad
Line 2,521 ⟶ 2,580:
if __name__ == '__main__':
tests = '''
978-17343145020596528126
978-17343145090596528120
978-1788399081
978-1788399083'''.strip().split()
Line 2,529 ⟶ 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,566 ⟶ 2,625:
print('\n'.join(
repr((s, isISBN13(s))) for s
in ["978-17343145020596528126",
"978-17343145090596528120",
"978-1788399081",
"978-1788399083"
Line 2,579 ⟶ 2,638:
</syntaxhighlight>
{{Out}}
<pre>('978-17343145020596528126', True)
('978-17343145090596528120', False)
('978-1788399081', True)
('978-1788399083', False)</pre>
Line 2,613 ⟶ 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,638 ⟶ 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,662 ⟶ 2,721:
"Bad check-digit $check; should be $check-digit"
} for words <
978-17343145020596528126
978-17343145090596528120
978-1788399081
978-1788399083
Line 2,670 ⟶ 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,698 ⟶ 2,757:
 
; check given examples
foreach [str] ["978-17343145020596528126" "978-17343145090596528120" "978-1788399081" "978-1788399083"] [
prin str
prin " - "
Line 2,707 ⟶ 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,717 ⟶ 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,746 ⟶ 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,771 ⟶ 2,883:
Output:
<pre>
978-17343145020596528126: true
978-17343145090596528120: bad
978-1788399081: true
978-1788399083: bad
Line 2,813 ⟶ 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,824 ⟶ 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,840 ⟶ 2,952:
{{out}}
<pre>
978-17343145020596528126: true
978-17343145090596528120: false
978-1788399081: true
978-1788399083: false
Line 2,877 ⟶ 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,883 ⟶ 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,901 ⟶ 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,928 ⟶ 3,093:
 
let cases = [
"978-17343145020596528126",
"978-17343145090596528120",
"978-1788399081",
"978-1788399083"
Line 2,941 ⟶ 3,106:
{{out}}
 
<pre>978-17343145020596528126 => good
978-17343145090596528120 => bad
978-1788399081 => good
978-1788399083 => bad</pre>
Line 2,963 ⟶ 3,128:
}
foreach test {
978-17343145020596528126
978-17343145090596528120
978-1788399081
978-1788399083
Line 2,970 ⟶ 3,135:
</syntaxhighlight>
{{out}}
<pre>978-17343145020596528126:true
978-17343145090596528120:false
978-1788399081:true
978-1788399083:false</pre>
Line 2,992 ⟶ 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,020 ⟶ 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,039 ⟶ 3,204:
}
 
for isbn in 978-17343145020596528126 978-17343145090596528120 978-1788399081 978-1788399083; do
printf '%s: ' "$isbn"
if check_isbn13 "$isbn"; then
Line 3,048 ⟶ 3,213:
done</syntaxhighlight>
{{Out}}
<pre>978-17343145020596528126: OK
978-17343145090596528120: NOT OK
978-1788399081: OK
978-1788399083: NOT OK</pre>
Line 3,076 ⟶ 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,116 ⟶ 3,281:
fn main() {
isbns := ["978-17343145020596528126", "978-17343145090596528120", "978-1788399081", "978-1788399083"]
for isbn in isbns {
mut res := "bad"
Line 3,128 ⟶ 3,293:
{{out}}
<pre>
978-17343145020596528126: good
978-17343145090596528120: bad
978-1788399081: good
978-1788399083: bad
Line 3,135 ⟶ 3,300:
 
=={{header|Wren}}==
<syntaxhighlight lang="ecmascriptwren">var isbn13 = Fn.new { |s|
var cps = s.codePoints
var digits = []
Line 3,152 ⟶ 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,159 ⟶ 3,324:
{{out}}
<pre>
978-17343145020596528126 -> good
978-17343145090596528120 -> bad
978-1788399081 -> good
978-1788399083 -> bad
Line 3,186 ⟶ 3,351:
];
 
[ISBN13("978-17343145020596528126");
ISBN13("978-17343145090596528120");
ISBN13("978-1788399081");
ISBN13("978-1788399083");
Line 3,196 ⟶ 3,361:
{{out}}
<pre>
978-17343145020596528126: good
978-17343145090596528120: bad
978-1788399081: good
978-1788399083: bad
Line 3,205 ⟶ 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,212 ⟶ 3,377:
<syntaxhighlight lang="zkl">isbns:=
#<<<"
978-17343145020596528126
978-17343145090596528120
978-1788399081
978-1788399083
Line 3,223 ⟶ 3,388:
{{out}}
<pre>
978-17343145020596528126 Good
978-17343145090596528120 Bad
978-1788399081 Good
978-1788399083 Bad
885

edits