ISBN13 check digit: Difference between revisions

m
(→‎{{header|Vlang}}: Rename "Vlang" in "V (Vlang)")
 
(25 intermediate revisions by 13 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 727 ⟶ 754:
0820424528 NG length
</pre>
 
=={{header|BASIC256}}==
{{trans|Ring}}
<syntaxhighlight lang="vb">arraybase 1
dim isbn = {"978-0596528126", "978-0596528120", "978-1788399081", "978-1788399083", "978-2-74839-908-0", "978-2-74839-908-5", "978 1 86197 876 9"}
 
for n = 1 to isbn[?]
sum = 0
isbnStr = isbn[n]
isbnStr = replace(isbnStr, "-", "")
isbnStr = replace(isbnStr, " ", "")
for m = 1 to length(isbnStr)
if m mod 2 = 0 then
num = 3 * int(mid(isbnStr, m, 1))
else
num = int(mid(isbnStr, m, 1))
end if
sum += num
next m
if sum mod 10 = 0 then
print isbn[n]; ": good"
else
print isbn[n]; ": bad"
end if
next n</syntaxhighlight>
 
=={{header|BCPL}}==
Line 757 ⟶ 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 795 ⟶ 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 804 ⟶ 856:
{{out}}
<pre>
978-17343145020596528126: good
978-17343145090596528120: bad
978-1788399081: good
978-1788399083: bad
Line 841 ⟶ 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 849 ⟶ 901:
}</syntaxhighlight>
{{out}}
<pre>978-17343145020596528126: good
978-17343145090596528120: bad
978-1788399081: good
978-1788399083: bad</pre>
Line 861 ⟶ 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 906 ⟶ 958:
po: stream := stream$primary_output()
tests: array[string] := array[string]$
["978-17343145020596528126",
"978-17343145090596528120",
"978-1788399081",
"978-1788399083"]
Line 921 ⟶ 973:
end start_up</syntaxhighlight>
{{out}}
<pre>978-17343145020596528126: good
978-17343145090596528120: bad
978-1788399081: good
978-1788399083: bad</pre>
Line 955 ⟶ 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,071 ⟶ 1,123:
{{out}}
 
<pre>978-17343145020596528126 (good)
978-17343145090596528120 (bad)
978-1788399081 (good)
978-1788399083 (bad)
Line 1,104 ⟶ 1,156:
var isbns: [uint8][] := {
"978-17343145020596528126", "978-17343145090596528120", "978-1788399081", "978-1788399083"
};
Line 1,116 ⟶ 1,168:
end loop;</syntaxhighlight>
{{out}}
<pre>978-17343145020596528126: good
978-17343145090596528120: bad
978-1788399081: good
978-1788399083: bad</pre>
Line 1,143 ⟶ 1,195:
 
unittest {
assert(isValidISBN13("978-17343145020596528126"));
assert(!isValidISBN13("978-17343145090596528120"));
assert(isValidISBN13("978-1788399081"));
assert(!isValidISBN13("978-1788399083"));
}</syntaxhighlight>
 
=={{header|Delphi}}==
{{works with|Delphi|6.0}}
{{libheader|SysUtils,StdCtrls}}
 
 
<syntaxhighlight lang="Delphi">
 
function ValidateISBN(ISBN: string): boolean;
{Validate an ISBN number}
var I,N,Sum: integer;
begin
Sum:=0;
{Go througha chars, ignoring non-digits}
for I:=1 to Length(ISBN) do
if ISBN[I] in ['0'..'9'] then
begin
N:=StrToInt(ISBN[I]);
{Every other digit multiplied by 3}
if (I and 1)=1 then N:=N*3;
{Sum digits}
Sum:=Sum+N;
end;
{The sum must be an even multiple of 10}
Result:=(Sum mod 10)=0;
end;
 
procedure ValidateAndShow(Memo: TMemo; ISBN: string);
{Validate ISBN number and show the result}
var S: string;
begin
S:=ISBN;
if ValidateISBN(ISBN) then S:=S+' (Good)'
else S:=S+' (Bad)';
Memo.Lines.Add(S);
end;
 
procedure TestISBNSet(Memo: TMemo);
{Test supplied set of ISBN numbers}
begin
ValidateAndShow(Memo,'978-0596528126'); //(good)
ValidateAndShow(Memo,'978-0596528120'); //(bad)
ValidateAndShow(Memo,'978-1788399081'); //(good)
ValidateAndShow(Memo,'978-1788399083'); //(bad)
end;
 
 
</syntaxhighlight>
{{out}}
<pre>
978-0596528126 (Good)
978-0596528120 (Bad)
978-1788399081 (Good)
978-1788399083 (Bad)
 
</pre>
 
 
=={{header|Draco}}==
Line 1,184 ⟶ 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>
 
=={{header|EasyLang}}==
<syntaxhighlight lang="text">
func ISBN13check isbn$ .
for c$ in strchars isbn$
if c$ <> "-"
ndigs += 1
.
dig = number c$
if ndigs mod 2 = 0
dig *= 3
.
sum += dig
.
if sum mod 10 <> 0
return 0
.
return 1
.
codes$[] = [ "978-0596528126" "978-0596528120" "978-1788399081" "978-1788399083" ]
for code$ in codes$[]
if ISBN13check code$ = 1
print code$ & " is a valid ISBN"
else
print code$ & " is not a valid ISBN"
.
.
</syntaxhighlight>
{{out}}
<pre>
978-0596528126 is a valid ISBN
978-0596528120 is not a valid ISBN
978-1788399081 is a valid ISBN
978-1788399083 is not a valid ISBN
</pre>
 
=={{header|Excel}}==
Line 1,273 ⟶ 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,302 ⟶ 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,325 ⟶ 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,336 ⟶ 1,480:
implicit none
 
character(len=14), dimension(4), parameter :: isbns=["978-17343145020596528126", "978-17343145090596528120", "978-1788399081", "978-1788399083"]
integer :: i
 
Line 1,373 ⟶ 1,517:
{{out}}
<pre>
978-17343145020596528126 : good
978-17343145090596528120 : bad
978-1788399081 : good
978-1788399083 : bad
Line 1,408 ⟶ 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,420 ⟶ 1,564:
{{out}}
<pre>
978-17343145020596528126: good
978-17343145090596528120: bad
978-1788399081: good
978-1788399083: bad
Line 1,448 ⟶ 1,592:
 
{{out}}
<pre>978-17343145020596528126 Valid ISBN13
978-17343145090596528120 Inalid ISBN13
978-1788399081 Valid ISBN13
978-1788399083 Inalid ISBN13</pre>
Line 1,455 ⟶ 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}}==
{{trans|BASIC256}}
<syntaxhighlight lang="vbnet">Public Sub Main()
Dim isbn As String[] = ["978-0596528126", "978-0596528120", "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
Dim sum As Integer = 0, num As Integer
Dim isbnStr As String = isbn[n]
isbnStr = Replace(isbnStr, "-", "")
isbnStr = Replace(isbnStr, " ", "")
For m As Integer = 1 To Len(isbnStr)
If m Mod 2 = 0 Then
num = 3 * CInt(Mid(isbnStr, m, 1))
Else
num = CInt(Mid(isbnStr, m, 1))
End If
sum += num
Next
If sum Mod 10 = 0 Then
Print isbn[n]; ": good"
Else
Print isbn[n]; ": bad"
End If
Next
End</syntaxhighlight>
 
=={{header|Go}}==
Line 1,494 ⟶ 1,672:
 
func main() {
isbns := []string{"978-17343145020596528126", "978-17343145090596528120", "978-1788399081", "978-1788399083"}
for _, isbn := range isbns {
res := "bad"
Line 1,506 ⟶ 1,684:
{{out}}
<pre>
978-17343145020596528126: good
978-17343145090596528120: bad
978-1788399081: good
978-1788399083: bad
Line 1,536 ⟶ 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,564 ⟶ 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,613 ⟶ 1,791:
{{out}}
 
<syntaxhighlight lang="j"> isbn13c;._1 ' 978-17343145020596528126 978-17343145090596528120 978-1788399081 978-1788399083'
1 0 1 0</syntaxhighlight>
 
=={{header|Java}}==
<syntaxhighlight lang="java">
public static void main(String[] args) {
String[] isbn13s = {
"978-0596528126",
"978-0596528120",
"978-1788399081",
"978-1788399083"
};
for (String isbn13 : isbn13s)
System.out.printf("%s %b%n", isbn13, validateISBN13(isbn13));
}
 
static boolean validateISBN13(String string) {
int[] digits = digits(string.strip().replace("-", ""));
return digits[12] == checksum(digits);
}
 
static int[] digits(String string) {
int[] digits = new int[13];
int index = 0;
for (char character : string.toCharArray()) {
if (character < '0' || character > '9')
throw new IllegalArgumentException("Invalid ISBN-13");
/* convert ascii to integer */
digits[index++] = Character.digit(character, 10);
}
return digits;
}
 
static int checksum(int[] digits) {
int total = 0;
int index = 0;
for (int digit : digits) {
if (index == 12) break;
if (index++ % 2 == 1) digit *= 3;
total += digit;
}
return 10 - (total % 10);
}
</syntaxhighlight>
<pre>
978-0596528126 true
978-0596528120 false
978-1788399081 true
978-1788399083 false
</pre>
<br />
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,657 ⟶ 1,883:
 
def testingcodes:
["978-17343145020596528126", "978-17343145090596528120",
"978-1788399081", "978-1788399083"];
Line 1,665 ⟶ 1,891:
{{out}}
<pre>
978-17343145020596528126: good
978-17343145090596528120: bad
978-1788399081: good
978-1788399083: bad
Line 1,677 ⟶ 1,903:
end
 
const testingcodes = ["978-17343145020596528126", "978-17343145090596528120",
"978-1788399081", "978-1788399083"]
 
Line 1,685 ⟶ 1,911:
</syntaxhighlight>{{out}}
<pre>
978-17343145020596528126: good
978-17343145090596528120: bad
978-1788399081: good
978-1788399083: bad
</pre>
 
=={{header|K}}==
{{works with|ngn/k}}
<syntaxhighlight lang=K>digits: {x[&(x>"/")&x<":"]-"0"}
isbn13c: 0=10!+/{x*(#x)#1 3} digits@
 
isbn13c "978-0596528126"
1
isbn13c "978-0596528120"
0
isbn13c " 978-1788399081"
1
isbn13c "978-1788399083"
0</syntaxhighlight>
 
=={{header|Kotlin}}==
Line 1,705 ⟶ 1,945:
describe("ISBN Utilities") {
mapOf(
"978-17343145020596528126" to true,
"978-17343145090596528120" to false,
"978-1788399081" to true,
"978-1788399083" to false
Line 1,722 ⟶ 1,962:
{{out}}
<pre>
978-17343145020596528126: good
978-17343145090596528120: bad
978-1788399081: good
978-1788399083: bad
Line 1,729 ⟶ 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 1,814 ⟶ 2,031:
 
function main()
test("978-17343145020596528126")
test("978-17343145090596528120")
test("978-1788399081")
test("978-1788399083")
Line 1,822 ⟶ 2,039:
main()</syntaxhighlight>
{{out}}
<pre>978-17343145020596528126: good
978-17343145090596528120: bad
978-1788399081: good
978-1788399083: bad</pre>
Line 1,840 ⟶ 2,057:
]
]
ValidISBNQ["978-17343145020596528126"]
ValidISBNQ["978-17343145090596528120"]
ValidISBNQ["978-1788399081"]
ValidISBNQ["978-1788399083"]</syntaxhighlight>
Line 1,850 ⟶ 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 1,891 ⟶ 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 1,931 ⟶ 2,206:
end
 
isbns = {"978-17343145020596528126", "978-17343145090596528120", "978-1788399081", "978-1788399083"}
for isbn in isbns
res = "bad"
Line 1,941 ⟶ 2,216:
end</syntaxhighlight>
{{out}}
<pre>978-17343145020596528126: good
978-17343145090596528120: bad
978-1788399081: good
978-1788399083: bad</pre>
Line 1,960 ⟶ 2,235:
 
when is_main_module:
let isbns = [ "978-17343145020596528126", "978-17343145090596528120",
"978-1788399081", "978-1788399083" ]
for isbn in isbns:
Line 1,967 ⟶ 2,242:
{{out}}
<pre>
978-17343145020596528126: good
978-17343145090596528120: bad
978-1788399081: good
978-1788399083: bad
Line 2,055 ⟶ 2,330:
{ === MAIN ============================================================= }
begin
writeLn(isValidISBNString('978-17343145020596528126'));
writeLn(isValidISBNString('978-17343145090596528120'));
writeLn(isValidISBNString('978-1788399081'));
writeLn(isValidISBNString('978-1788399083'))
Line 2,077 ⟶ 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,083 ⟶ 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,110 ⟶ 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,116 ⟶ 2,391:
{{out}}
<pre>
978-17343145020596528126: good
978-17343145090596528120: bad
978-1788399081: good
978-1788399083: bad
Line 2,141 ⟶ 2,416:
(if (isbn13? A) 'ok 'fail) ) )
(quote
"978-17343145020596528126"
"978-17343145090596528120"
"978-1-86197-876-9"
"978-2-74839-908-5"
Line 2,148 ⟶ 2,423:
{{out}}
<pre>
978-17343145020596528126 ok
978-17343145090596528120 fail
978-1-86197-876-9 ok
978-2-74839-908-5 fail
Line 2,191 ⟶ 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,210 ⟶ 2,485:
EOF</syntaxhighlight>
{{out}}
<pre>978-17343145020596528126: GOOD
978-17343145090596528120: BAD
978-1788399081: GOOD
978-1788399083: BAD</pre>
Line 2,219 ⟶ 2,494:
function Get-ISBN13 {
$codes = (
"978-17343145020596528126",
"978-17343145090596528120",
"978-1788399081",
"978-1788399083"
Line 2,259 ⟶ 2,534:
{{out}}
<pre>
978-17343145020596528126 Good
978-17343145090596528120 Bad
978-1788399081 Good
978-1788399083 Bad
Line 2,281 ⟶ 2,556:
 
If OpenConsole()
TestISBN13("978-17343145020596528126")
TestISBN13("978-17343145090596528120")
TestISBN13("978-1788399081")
TestISBN13("978-1788399083")
Line 2,288 ⟶ 2,563:
EndIf</syntaxhighlight>
{{out}}
<pre>978-17343145020596528126 good
978-17343145090596528120 bad
978-1788399081 good
978-1788399083 bad
Line 2,305 ⟶ 2,580:
if __name__ == '__main__':
tests = '''
978-17343145020596528126
978-17343145090596528120
978-1788399081
978-1788399083'''.strip().split()
Line 2,313 ⟶ 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,350 ⟶ 2,625:
print('\n'.join(
repr((s, isISBN13(s))) for s
in ["978-17343145020596528126",
"978-17343145090596528120",
"978-1788399081",
"978-1788399083"
Line 2,363 ⟶ 2,638:
</syntaxhighlight>
{{Out}}
<pre>('978-17343145020596528126', True)
('978-17343145090596528120', False)
('978-1788399081', True)
('978-1788399083', False)</pre>
Line 2,397 ⟶ 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,422 ⟶ 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,446 ⟶ 2,721:
"Bad check-digit $check; should be $check-digit"
} for words <
978-17343145020596528126
978-17343145090596528120
978-1788399081
978-1788399083
Line 2,454 ⟶ 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,482 ⟶ 2,757:
 
; check given examples
foreach [str] ["978-17343145020596528126" "978-17343145090596528120" "978-1788399081" "978-1788399083"] [
prin str
prin " - "
Line 2,491 ⟶ 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,501 ⟶ 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,530 ⟶ 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,555 ⟶ 2,883:
Output:
<pre>
978-17343145020596528126: true
978-17343145090596528120: bad
978-1788399081: true
978-1788399083: bad
Line 2,564 ⟶ 2,892:
</pre>
 
=={{header|RPL}}==
{{works with|Halcyon Calc|4.2.7}}
≪ → isbn
≪ 0 1 CF
1 isbn SIZE FOR j
IF "0123456789" isbn j DUP SUB POS THEN
LAST 1 -
IF 1 FS?C THEN 3 * ELSE 1 SF END
+
END
NEXT
10 MOD NOT
'ISBN?' STO
 
≪ { "978-0596528126" "978-0596528120" "978-1788399081" "978-1788399083" } → tests
≪ 1 tests SIZE FOR j tests GET ISBN? NEXT ≫
≫ EVAL
{{out}}
<pre>
4: 1
3: 0
2: 1
1: 0
</pre>
=={{header|Ruby}}==
<syntaxhighlight lang="ruby">def validISBN13?(str)
Line 2,571 ⟶ 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,582 ⟶ 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,598 ⟶ 2,952:
{{out}}
<pre>
978-17343145020596528126: true
978-17343145090596528120: false
978-1788399081: true
978-1788399083: false
Line 2,635 ⟶ 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,641 ⟶ 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,659 ⟶ 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,686 ⟶ 3,093:
 
let cases = [
"978-17343145020596528126",
"978-17343145090596528120",
"978-1788399081",
"978-1788399083"
Line 2,699 ⟶ 3,106:
{{out}}
 
<pre>978-17343145020596528126 => good
978-17343145090596528120 => bad
978-1788399081 => good
978-1788399083 => bad</pre>
Line 2,721 ⟶ 3,128:
}
foreach test {
978-17343145020596528126
978-17343145090596528120
978-1788399081
978-1788399083
Line 2,728 ⟶ 3,135:
</syntaxhighlight>
{{out}}
<pre>978-17343145020596528126:true
978-17343145090596528120:false
978-1788399081:true
978-1788399083:false</pre>
Line 2,750 ⟶ 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 2,778 ⟶ 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 2,797 ⟶ 3,204:
}
 
for isbn in 978-17343145020596528126 978-17343145090596528120 978-1788399081 978-1788399083; do
printf '%s: ' "$isbn"
if check_isbn13 "$isbn"; then
Line 2,806 ⟶ 3,213:
done</syntaxhighlight>
{{Out}}
<pre>978-17343145020596528126: OK
978-17343145090596528120: NOT OK
978-1788399081: OK
978-1788399083: NOT OK</pre>
Line 2,834 ⟶ 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 2,874 ⟶ 3,281:
fn main() {
isbns := ["978-17343145020596528126", "978-17343145090596528120", "978-1788399081", "978-1788399083"]
for isbn in isbns {
mut res := "bad"
Line 2,886 ⟶ 3,293:
{{out}}
<pre>
978-17343145020596528126: good
978-17343145090596528120: bad
978-1788399081: good
978-1788399083: bad
Line 2,893 ⟶ 3,300:
 
=={{header|Wren}}==
<syntaxhighlight lang="ecmascriptwren">var isbn13 = Fn.new { |s|
var cps = s.codePoints
var digits = []
Line 2,910 ⟶ 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 2,917 ⟶ 3,324:
{{out}}
<pre>
978-17343145020596528126 -> good
978-17343145090596528120 -> bad
978-1788399081 -> good
978-1788399083 -> bad
Line 2,944 ⟶ 3,351:
];
 
[ISBN13("978-17343145020596528126");
ISBN13("978-17343145090596528120");
ISBN13("978-1788399081");
ISBN13("978-1788399083");
Line 2,954 ⟶ 3,361:
{{out}}
<pre>
978-17343145020596528126: good
978-17343145090596528120: bad
978-1788399081: good
978-1788399083: bad
Line 2,963 ⟶ 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 2,970 ⟶ 3,377:
<syntaxhighlight lang="zkl">isbns:=
#<<<"
978-17343145020596528126
978-17343145090596528120
978-1788399081
978-1788399083
Line 2,981 ⟶ 3,388:
{{out}}
<pre>
978-17343145020596528126 Good
978-17343145090596528120 Bad
978-1788399081 Good
978-1788399083 Bad
885

edits