8000 Add International Standard Name Identifier · zipus/python-stdnum@928a09d · GitHub
[go: up one dir, main page]

Skip to content

Commit 928a09d

Browse files
committed
Add International Standard Name Identifier
Closes arthurdejong#463
1 parent 2b92075 commit 928a09d

File tree

1 file changed

+81
-0
lines changed

1 file changed

+81
-0
lines changed

stdnum/isni.py

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
# isni.py - functions for handling International Standard Name Identifiers
2+
#
3+
# Copyright (C) 2025 Arthur de Jong
4+
#
5+
# This library is free software; you can redistribute it and/or
6+
# modify it under the terms of the GNU Lesser General Public
7+
# License as published by the Free Software Foundation; either
8+
# version 2.1 of the License, or (at your option) any later version.
9+
#
10+
# This library is distributed in the hope that it will be useful,
11+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13+
# Lesser General Public License for more details.
14+
#
15+
# You should have received a copy of the GNU Lesser General Public
16+
# License along with this library; if not, write to the Free Software
17+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18+
# 02110-1301 USA
19+
20+
"""ISNI (International Standard Name Identifier).
21+
22+
The International Standard Name Identifier (ISNI) is used to identify
23+
contributors to media content such as books, television programmes, and
24+
newspaper articles. The number consists of 16 digits where the last character
25+
is a check digit.
26+
27+
More information:
28+
29+
* https://en.wikipedia.org/wiki/International_Standard_Name_Identifier
30+
* https://isni.org/
31+
32+
>>> validate('0000 0001 2281 955X')
33+
'000000012281955X'
34+
>>> validate('0000 0001 1111 955X')
35+
Traceback (most recent call last):
36+
...
37+
InvalidChecksum: ...
38+
>>> validate('0000 0001 2281')
39+
Traceback (most recent call last):
40+
...
41+
InvalidLength: ...
42+
>>> format('000000012281955X')
43+
'0000 0001 2281 955X'
44+
"""
45+
46+
47+
from stdnum.exceptions import *
48+
from stdnum.iso7064 import mod_11_2
49+
from stdnum.util import clean, isdigits
50+
51+
52+
def compact(number):
53+
"""Convert the ISNI to the minimal representation. This strips the number
54+
of any valid ISNI separators and removes surrounding whitespace."""
55+
return clean(number, ' -').strip().upper()
56+
57+
58+
def validate(number):
59+
"""Check if the number is a valid ISNI. This checks the length and
60+
whether the check digit is correct."""
61+
number = compact(number)
62+
if not isdigits(number[:-1]):
63+
raise InvalidFormat()
64+
if len(number) != 16:
65+
raise InvalidLength()
66+
mod_11_2.validate(number)
67+
return number
68+
69+
70+
def is_valid(number):
71+
"""Check if the number provided is a valid ISNI."""
72+
try:
73+
return bool(validate(number))
74+
except ValidationError:
75+
return False
76+
77+
78+
def format(number):
79+
"""Reformat the number to the standard presentation format."""
80+
number = compact(number)
81+
return ' '.join((number[:4], number[4:8], number[8:12], number[12:16]))

0 commit comments

Comments
 (0)
0