ISBN13 check digit: Difference between revisions
Langurmonkey (talk | contribs) |
Thundergnat (talk | contribs) (→{{header|Perl 6}}: Add a Perl 6 example) |
||
Line 100: | Line 100: | ||
978-1788399081: good |
978-1788399081: good |
||
978-1788399083: bad</pre> |
978-1788399083: bad</pre> |
||
=={{header|Perl 6}}== |
|||
{{works with|Rakudo|2019.11}} |
|||
Also test a value that has a zero check digit. |
|||
<lang perl6>sub check-digit ($isbn) { |
|||
(10 - (sum (|$isbn.comb(/<[0..9]>/)) »*» (1,3)) % 10).substr: *-1 |
|||
} |
|||
{ |
|||
my $check = .substr(*-1); |
|||
my $check-digit = check-digit .chop; |
|||
say "$_ : ", $check == $check-digit ?? |
|||
'Good' !! |
|||
"Bad check-digit $check; should be $check-digit" |
|||
} for words < |
|||
978-1734314502 |
|||
978-1734314509 |
|||
978-1788399081 |
|||
978-1788399083 |
|||
978-2-74839-908-0 |
|||
978-2-74839-908-5 |
|||
>;</lang> |
|||
{{out}} |
|||
<pre>978-1734314502 : Good |
|||
978-1734314509 : Bad check-digit 9; should be 2 |
|||
978-1788399081 : Good |
|||
978-1788399083 : Bad check-digit 3; should be 1 |
|||
978-2-74839-908-0 : Good |
|||
978-2-74839-908-5 : Bad check-digit 5; should be 0 |
|||
</pre> |
|||
=={{header|Python}}== |
=={{header|Python}}== |
Revision as of 18:14, 4 December 2019
- Task
Validate the check digit of an ISBN-13 code. Multiply every other digit by 3. Add the digits together. Take the remainder of division by 10. If it is 0, the ISBN-13 check digit is correct.
Use the following codes for testing:
978-1734314502: good 978-1734314509: bad 978-1788399081: good 978-1788399083: bad
Show output here, on this page
- See also
See https://isbn-information.com/the-13-digit-isbn.html for details on the method of validation.
Go
<lang go>package main
import (
"fmt" "strings" "unicode/utf8"
)
func checkIsbn13(isbn string) bool {
// remove any hyphens or spaces isbn = strings.ReplaceAll(strings.ReplaceAll(isbn, "-", ""), " ", "") // check length == 13 le := utf8.RuneCountInString(isbn) if le != 13 { return false } // check only contains digits and calculate weighted sum sum := int32(0) for i, c := range isbn { if c < '0' || c > '9' { return false } if i%2 == 0 { sum += c - '0' } else { sum += 3 * (c - '0') } } return sum%10 == 0
}
func main() {
isbns := []string{"978-1734314502", "978-1734314509", "978-1788399081", "978-1788399083"} for _, isbn := range isbns { res := "bad" if checkIsbn13(isbn) { res = "good" } fmt.Printf("%s: %s\n", isbn, res) }
}</lang>
- Output:
978-1734314502: good 978-1734314509: bad 978-1788399081: good 978-1788399083: bad
langur
<lang langur>val .isbn13checkdigit = f(.n) {
val .s = replace(.n, RE/[\- ]/, ZLS) if len(.s) != 13 { return false } # multiply every other number by 3 val .nums = map( f(.i, .d) if(.i rem 2 == 0: .d x 3; .d), series(13), map f .c-'0', s2cp .s, ) fold(f .x + .y, .nums) rem 10 == 0
}
val .tests = h{
"978-1734314502": true, "978-1734314509": false, "978-1788399081": true, "978-1788399083": false,
}
for .key in sort(keys .tests) {
val .pass = .isbn13checkdigit(.key) write .key, ": ", if(.pass: "good"; "bad") writeln if(.pass == .tests[.key]: ""; " (ISBN-13 CHECK DIGIT TEST FAILED)")
}</lang>
- Output:
978-1734314502: good 978-1734314509: bad 978-1788399081: good 978-1788399083: bad
Perl 6
Also test a value that has a zero check digit.
<lang perl6>sub check-digit ($isbn) {
(10 - (sum (|$isbn.comb(/<[0..9]>/)) »*» (1,3)) % 10).substr: *-1
}
{
my $check = .substr(*-1); my $check-digit = check-digit .chop; say "$_ : ", $check == $check-digit ?? 'Good' !! "Bad check-digit $check; should be $check-digit"
} for words <
978-1734314502 978-1734314509 978-1788399081 978-1788399083 978-2-74839-908-0 978-2-74839-908-5
>;</lang>
- Output:
978-1734314502 : Good 978-1734314509 : Bad check-digit 9; should be 2 978-1788399081 : Good 978-1788399083 : Bad check-digit 3; should be 1 978-2-74839-908-0 : Good 978-2-74839-908-5 : Bad check-digit 5; should be 0
Python
<lang python>def is_isbn13(n):
n = n.replace('-',).replace(' ', ) if len(n) != 13: return False product = (sum(int(ch) for ch in n[::2]) + sum(int(ch) * 3 for ch in n[1::2])) return product % 10 == 0
if __name__ == '__main__':
tests =
978-1734314502 978-1734314509 978-1788399081 978-1788399083.strip().split()
for t in tests: print(f"ISBN13 {t} validates {is_isbn13(t)}")</lang>
- Output:
ISBN13 978-1734314502 validates True ISBN13 978-1734314509 validates False ISBN13 978-1788399081 validates True ISBN13 978-1788399083 validates False