///|
/// 校验 ISBN-10(允许连字符与空格,校验位可为 X)。
///
/// 校验规则:第 i 位(1-based)乘以权重 `11 - i` 求和,和须能被 11 整除;
/// 校验位 X 表示 10。
pub fn isbn10_valid(s : String) -> Bool {
let d = strip_separators(s)
if d.length() != 10 {
return false
}
let b = @utf8.encode(d)
let mut sum = 0
for i = 0; i < 10; i = i + 1 {
let c = b[i]
let v = if i == 9 && (c == b'X' || c == b'x') {
10
} else if c >= b'0' && c <= b'9' {
(c - b'0').to_int()
} else {
return false
}
sum = sum + v * (10 - i)
}
sum % 11 == 0
}
///|
/// 校验 ISBN-13(允许连字符与空格),规则同 EAN-13。
pub fn isbn13_valid(s : String) -> Bool {
let d = strip_separators(s)
if d.length() != 13 {
return false
}
mod10_verify(d, 1, 3)
}
///|
/// 校验 ISSN(允许连字符与空格,校验位可为 X)。
///
/// 校验规则:前 7 位乘以权重 8..2 求和,校验位 = `(11 - sum % 11) % 11`,
/// 10 记作 X,11 记作 0。
pub fn issn_valid(s : String) -> Bool {
let d = strip_separators(s)
if d.length() != 8 {
return false
}
let b = @utf8.encode(d)
let mut sum = 0
for i = 0; i < 7; i = i + 1 {
let c = b[i]
if c < b'0' || c > b'9' {
return false
}
sum = sum + (c - b'0').to_int() * (8 - i)
}
let check = (11 - sum % 11) % 11
let c = b[7]
if c == b'X' || c == b'x' {
check == 10
} else if c >= b'0' && c <= b'9' {
(c - b'0').to_int() == check
} else {
false
}
}
///|
/// 计算 GTIN-14(14 位,ITF-14 使用的数据结构)的校验位。
/// 输入为 13 位负载,权重从左起奇位为 3、偶位为 1。
pub fn gtin14_checksum(data : String) -> Result[Int, String] {
let d = strip_separators(data)
if d.length() != 13 {
return Err("GTIN-14 requires 13 payload digits")
}
mod10_check(d, 3, 1)
}
///|
/// 校验完整的 GTIN-14(含校验位)。
pub fn gtin14_valid(s : String) -> Bool {
let d = strip_separators(s)
if d.length() != 14 {
return false
}
mod10_verify(d, 3, 1)
}