Skip to content

Commit 4e45d5c

Browse files
authored
Add hash validators (#57)
Add hash validators for md5, sha2, sha224, sha256, sha512
1 parent 2e0aed3 commit 4e45d5c

8 files changed

Lines changed: 287 additions & 0 deletions

File tree

docs/index.rst

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,46 @@ mac_address
120120
.. autofunction:: mac_address
121121

122122

123+
md5
124+
-----------
125+
126+
.. module:: validators.hashes
127+
128+
.. autofunction:: md5
129+
130+
131+
sha1
132+
-----------
133+
134+
.. module:: validators.hashes
135+
136+
.. autofunction:: sha1
137+
138+
139+
sha224
140+
-----------
141+
142+
.. module:: validators.hashes
143+
144+
.. autofunction:: sha224
145+
146+
147+
sha256
148+
-----------
149+
150+
.. module:: validators.hashes
151+
152+
.. autofunction:: sha256
153+
154+
155+
sha512
156+
-----------
157+
158+
.. module:: validators.hashes
159+
160+
.. autofunction:: sha512
161+
162+
123163
slug
124164
----
125165

tests/test_md5.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# -*- coding: utf-8 -*-
2+
import pytest
3+
4+
import validators
5+
6+
7+
@pytest.mark.parametrize('value', [
8+
'd41d8cd98f00b204e9800998ecf8427e',
9+
'D41D8CD98F00B204E9800998ECF8427E'
10+
])
11+
def test_returns_true_on_valid_md5(value):
12+
assert validators.md5(value)
13+
14+
15+
@pytest.mark.parametrize('value', [
16+
'z41d8cd98f00b204e9800998ecf8427e',
17+
'z8cd98f00b204e9800998ecf8427e',
18+
'z4aaaa1d8cd98f00b204e9800998ecf8427e'
19+
])
20+
def test_returns_failed_validation_on_invalid_md5(value):
21+
result = validators.md5(value)
22+
assert isinstance(result, validators.ValidationFailure)

tests/test_sha1.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# -*- coding: utf-8 -*-
2+
import pytest
3+
4+
import validators
5+
6+
7+
@pytest.mark.parametrize('value', [
8+
'da39a3ee5e6b4b0d3255bfef95601890afd80709',
9+
'DA39A3EE5E6B4B0D3255BFEF95601890AFD80709'
10+
])
11+
def test_returns_true_on_valid_sha1(value):
12+
assert validators.sha1(value)
13+
14+
15+
@pytest.mark.parametrize('value', [
16+
'za39a3ee5e6b4b0d3255bfef95601890afd80709',
17+
'da39e5e6b4b0d3255bfef95601890afd80709',
18+
'daaaa39a3ee5e6b4b0d3255bfef95601890afd80709'
19+
])
20+
def test_returns_failed_validation_on_invalid_sha1(value):
21+
result = validators.sha1(value)
22+
assert isinstance(result, validators.ValidationFailure)

tests/test_sha224.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# -*- coding: utf-8 -*-
2+
import pytest
3+
4+
import validators
5+
6+
7+
@pytest.mark.parametrize('value', [
8+
'd14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f',
9+
'D14A028C2A3A2BC9476102BB288234C415A2B01F828EA62AC5B3E42F'
10+
])
11+
def test_returns_true_on_valid_sha224(value):
12+
assert validators.sha224(value)
13+
14+
15+
@pytest.mark.parametrize('value', [
16+
'z14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f',
17+
'd028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f',
18+
'daaa14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f'
19+
])
20+
def test_returns_failed_validation_on_invalid_sha224(value):
21+
result = validators.sha224(value)
22+
assert isinstance(result, validators.ValidationFailure)

tests/test_sha256.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# -*- coding: utf-8 -*-
2+
import pytest
3+
4+
import validators
5+
6+
7+
@pytest.mark.parametrize('value', [
8+
'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855',
9+
'E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855'
10+
])
11+
def test_returns_true_on_valid_sha256(value):
12+
assert validators.sha256(value)
13+
14+
15+
@pytest.mark.parametrize('value', [
16+
'z3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855',
17+
'ec44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855',
18+
'eaaaa3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855',
19+
])
20+
def test_returns_failed_validation_on_invalid_sha256(value):
21+
result = validators.sha256(value)
22+
assert isinstance(result, validators.ValidationFailure)

tests/test_sha512.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# -*- coding: utf-8 -*-
2+
import pytest
3+
4+
import validators
5+
6+
7+
@pytest.mark.parametrize('value', [
8+
(
9+
'cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d'
10+
'13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e'
11+
),
12+
(
13+
'CF83E1357EEFB8BDF1542850D66D8007D620E4050B5715DC83F4A921D36CE9CE47D0D'
14+
'13C5D85F2B0FF8318D2877EEC2F63B931BD47417A81A538327AF927DA3E'
15+
)
16+
])
17+
def test_returns_true_on_valid_sha512(value):
18+
assert validators.sha512(value)
19+
20+
21+
@pytest.mark.parametrize('value', [
22+
(
23+
'zf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d'
24+
'13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e'
25+
),
26+
(
27+
'cf8357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c'
28+
'5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e'
29+
),
30+
(
31+
'cf8aaaa3e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce4'
32+
'7d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e'
33+
)
34+
])
35+
def test_returns_failed_validation_on_invalid_sha512(value):
36+
result = validators.sha512(value)
37+
assert isinstance(result, validators.ValidationFailure)

validators/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from .domain import domain # noqa
33
from .email import email # noqa
44
from .extremes import Max, Min # noqa
5+
from .hashes import md5, sha1, sha224, sha256, sha512 # noqa
56
from .i18n import fi_business_id, fi_ssn # noqa
67
from .iban import iban # noqa
78
from .ip_address import ipv4, ipv6 # noqa

validators/hashes.py

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
import re
2+
3+
from .utils import validator
4+
5+
md5_regex = re.compile(
6+
r"^[0-9a-f]{32}$",
7+
re.IGNORECASE
8+
)
9+
sha1_regex = re.compile(
10+
r"^[0-9a-f]{40}$",
11+
re.IGNORECASE
12+
)
13+
sha224_regex = re.compile(
14+
r"^[0-9a-f]{56}$",
15+
re.IGNORECASE
16+
)
17+
sha256_regex = re.compile(
18+
r"^[0-9a-f]{64}$",
19+
re.IGNORECASE
20+
)
21+
sha512_regex = re.compile(
22+
r"^[0-9a-f]{128}$",
23+
re.IGNORECASE
24+
)
25+
26+
27+
@validator
28+
def md5(value):
29+
"""
30+
Return whether or not given value is a valid MD5 hash.
31+
32+
Examples::
33+
34+
>>> md5('d41d8cd98f00b204e9800998ecf8427e')
35+
True
36+
37+
>>> md5('900zz11')
38+
ValidationFailure(func=md5, args={'value': '900zz11'})
39+
40+
:param value: MD5 string to validate
41+
"""
42+
return md5_regex.match(value)
43+
44+
45+
@validator
46+
def sha1(value):
47+
"""
48+
Return whether or not given value is a valid SHA1 hash.
49+
50+
Examples::
51+
52+
>>> sha1('da39a3ee5e6b4b0d3255bfef95601890afd80709')
53+
True
54+
55+
>>> sha1('900zz11')
56+
ValidationFailure(func=sha1, args={'value': '900zz11'})
57+
58+
:param value: SHA1 string to validate
59+
"""
60+
return sha1_regex.match(value)
61+
62+
63+
@validator
64+
def sha224(value):
65+
"""
66+
Return whether or not given value is a valid SHA224 hash.
67+
68+
Examples::
69+
70+
>>> sha224('d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f')
71+
True
72+
73+
>>> sha224('900zz11')
74+
ValidationFailure(func=sha224, args={'value': '900zz11'})
75+
76+
:param value: SHA224 string to validate
77+
"""
78+
return sha224_regex.match(value)
79+
80+
81+
@validator
82+
def sha256(value):
83+
"""
84+
Return whether or not given value is a valid SHA256 hash.
85+
86+
Examples::
87+
88+
>>> sha256(
89+
... 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b'
90+
... '855'
91+
... )
92+
True
93+
94+
>>> sha256('900zz11')
95+
ValidationFailure(func=sha256, args={'value': '900zz11'})
96+
97+
:param value: SHA256 string to validate
98+
"""
99+
return sha256_regex.match(value)
100+
101+
102+
@validator
103+
def sha512(value):
104+
"""
105+
Return whether or not given value is a valid SHA512 hash.
106+
107+
Examples::
108+
109+
>>> sha512(
110+
... 'cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce'
111+
... '9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af9'
112+
... '27da3e'
113+
... )
114+
True
115+
116+
>>> sha512('900zz11')
117+
ValidationFailure(func=sha512, args={'value': '900zz11'})
118+
119+
:param value: SHA512 string to validate
120+
"""
121+
return sha512_regex.match(value)

0 commit comments

Comments
 (0)