Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: adds base58 and base64 validators #351

Merged
merged 1 commit into from
Apr 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 20 additions & 1 deletion CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,25 @@ Note to self: Breaking changes must increment either

-->

## 0.26.0 (2024-04-02)

_**Breaking**_

> No breaking changes were introduced in this version.

_**Features**_

- feat: adds `base58` and `base64` validators by @yozachar in [#351](https://github.com/python-validators/validators/pull/351)

_**Maintenance**_

- fix: regex ignore-case uses only `a-z` by @yozachar in [#349](https://github.com/python-validators/validators/pull/349)
- patch: supported extended latin in username by @yozachar in [#350](https://github.com/python-validators/validators/pull/350)

**Full Changelog**: [`0.25.0...0.26.0`](https://github.com/python-validators/validators/compare/0.25.0...0.26.0)

---

## 0.25.0 (2024-04-02)

_**Breaking**_
Expand All @@ -24,7 +43,7 @@ _**Maintenance**_
- maint: adds quick start docs by @yozachar in [#344](https://github.com/python-validators/validators/pull/344)
- fix: `domain` validation is now more consistent across rfcs by @yozachar in [#347](https://github.com/python-validators/validators/pull/347)

**Full Changelog**: [`0.24.2...0.25.0`](https://github.com/python-validators/validators/compare/0.23.2...0.24.0)
**Full Changelog**: [`0.24.2...0.25.0`](https://github.com/python-validators/validators/compare/0.24.2...0.25.0)

---

Expand Down
2 changes: 1 addition & 1 deletion SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

| Version | Supported |
| ---------- | ------------------ |
| `>=0.25.0` | :white_check_mark: |
| `>=0.26.0` | :white_check_mark: |

## Reporting a Vulnerability

Expand Down
2 changes: 2 additions & 0 deletions docs/api/hashes.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# hashes

::: validators.hashes.base58
::: validators.hashes.base64
::: validators.hashes.md5
::: validators.hashes.sha1
::: validators.hashes.sha224
Expand Down
2 changes: 2 additions & 0 deletions docs/api/hashes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ hashes
------

.. module:: validators.hashes
.. autofunction:: base58
.. autofunction:: base64
.. autofunction:: md5
.. autofunction:: sha1
.. autofunction:: sha224
Expand Down
6 changes: 4 additions & 2 deletions src/validators/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from .cron import cron
from .domain import domain
from .email import email
from .hashes import md5, sha1, sha224, sha256, sha512
from .hashes import base58, base64, md5, sha1, sha224, sha256, sha512
from .hostname import hostname
from .i18n import es_cif, es_doi, es_nie, es_nif, fi_business_id, fi_ssn, fr_department, fr_ssn
from .iban import iban
Expand Down Expand Up @@ -46,6 +46,8 @@
# ...
"email",
# hashes
"base58",
"base64",
"md5",
"sha1",
"sha224",
Expand Down Expand Up @@ -82,4 +84,4 @@
"validator",
)

__version__ = "0.25.0"
__version__ = "0.26.0"
46 changes: 46 additions & 0 deletions src/validators/hashes.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,52 @@
from .utils import validator


@validator
def base58(value: str, /):
"""Return whether or not given value is a valid base58 hash.

Examples:
>>> base58('14pq6y9H2DLGahPsM4s7ugsNSD2uxpHsJx')
# Output: True
>>> base58('cUSECm5YzcXJwP')
# Output: ValidationError(func=base58, args={'value': 'cUSECm5YzcXJwP'})

Args:
value:
base58 string to validate.

Returns:
(Literal[True]): If `value` is a valid base58 hash.
(ValidationError): If `value` is an invalid base58 hash.
"""
return re.match(r"^[1-9A-HJ-NP-Za-km-z]+$", value) if value else False


@validator
def base64(value: str, /):
"""Return whether or not given value is a valid base64 hash.

Examples:
>>> base64('Y2hhcmFjdGVyIHNldA==')
# Output: True
>>> base64('cUSECm5YzcXJwP')
# Output: ValidationError(func=base64, args={'value': 'cUSECm5YzcXJwP'})

Args:
value:
base64 string to validate.

Returns:
(Literal[True]): If `value` is a valid base64 hash.
(ValidationError): If `value` is an invalid base64 hash.
"""
return (
re.match(r"^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$", value)
if value
else False
)


@validator
def md5(value: str, /):
"""Return whether or not given value is a valid MD5 hash.
Expand Down
49 changes: 48 additions & 1 deletion tests/test_hashes.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,54 @@
import pytest

# local
from validators import ValidationError, md5, sha1, sha224, sha256, sha512
from validators import ValidationError, base58, base64, md5, sha1, sha224, sha256, sha512

# ==> base58 <== #


@pytest.mark.parametrize(
"value",
[
"cUSECaVvAiV3srWbFRvVPzm5YzcXJwPSwZfE7veYPHoXmR9h6YMQ",
"18KToMF5ckjXBYt2HAj77qsG3GPeej3PZn",
"n4FFXRNNEW1aA2WPscSuzHTCjzjs4TVE2Z",
"38XzQ9dPGb1uqbZsjPtUajp7omy8aefjqj",
],
)
def test_returns_true_on_valid_base58(value: str):
"""Test returns true on valid base58."""
assert base58(value)


@pytest.mark.parametrize(
"value",
["ThisIsAReallyLongStringThatIsDefinitelyNotBase58Encoded", "abcABC!@#", "InvalidBase58!"],
)
def test_returns_failed_validation_on_invalid_base58(value: str):
"""Test returns failed validation on invalid base58."""
assert isinstance(base58(value), ValidationError)


# ==> base64 <== #


@pytest.mark.parametrize(
"value",
["SGVsbG8gV29ybGQ=", "U29tZSBkYXRhIHN0cmluZw==", "YW55IGNhcm5hbCBwbGVhcw=="],
)
def test_returns_true_on_valid_base64(value: str):
"""Test returns true on valid base64."""
assert base64(value)


@pytest.mark.parametrize(
"value",
["SGVsbG8gV29ybGQ", "U29tZSBkYXRhIHN0cmluZw", "YW55IGNhcm5hbCBwbGVhc"],
)
def test_returns_failed_validation_on_invalid_base64(value: str):
"""Test returns failed validation on invalid base64."""
assert isinstance(base64(value), ValidationError)


# ==> md5 <== #

Expand Down