Skip to content

Commit

Permalink
feat: added is_freight_container_id validator
Browse files Browse the repository at this point in the history
  • Loading branch information
theteladras committed Nov 16, 2023
1 parent 5f08645 commit ffb23f7
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 2 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ Validator | Description
**is_even(str/int)** | checks if the input is an even number, it accepts either a string or an int.
**is_float(str, options)** | check if the string is a float.<br/><br/>`options` is an dictionary which can contain the keys `min`, `max`, `gt`, and/or `lt` to validate the float is within boundaries (e.g. `{ "min": 7.22, "max": 9.55 }`) it also has `locale` as an option.<br/><br/>`min` and `max` are equivalent to 'greater or equal' and 'less or equal', respectively while `gt` and `lt` are their strict counterparts.<br/><br/>`locale` determine the decimal separator and is one of `['ar', 'ar-AE', 'ar-BH', 'ar-DZ', 'ar-EG', 'ar-IQ', 'ar-JO', 'ar-KW', 'ar-LB', 'ar-LY', 'ar-MA', 'ar-QA', 'ar-QM', 'ar-SA', 'ar-SD', 'ar-SY', 'ar-TN', 'ar-YE', 'bg-BG', 'cs-CZ', 'da-DK', 'de-DE', 'en-AU', 'en-GB', 'en-HK', 'en-IN', 'en-NZ', 'en-US', 'en-ZA', 'en-ZM', 'es-ES', 'fr-CA', 'fr-FR', 'hu-HU', 'it-IT', 'nb-NO', 'nl-NL', 'nn-NO', 'pl-PL', 'pt-BR', 'pt-PT', 'ru-RU', 'sl-SI', 'sr-RS', 'sr-RS@latin', 'sv-SE', 'tr-TR', 'uk-UA']`. Locale list is `validator.isFloatLocales`.
**is_fqdn(str, options)** | check if the string is a fully qualified domain name (e.g. domain.com).<br/><br/>`options` is an dictionary which defaults to `{ "require_tld": True, "allow_underscores": False, "allow_trailing_dot": False, "allow_numeric_tld": False, "allow_wildcard": False }`. If `allow_wildcard` is set to *True*, the validator will allow domain starting with `*.` (e.g. `*.example.com` or `*.shop.example.com`).
**is_freight_container_id(str)** | alias for `isISO6346`, check if the string is a valid [ISO 6346](https://en.wikipedia.org/wiki/ISO_6346) shipping container identification.
**is_full_width(str)** | check if the string contains any full-width chars.
**is_hash(str, algorithm)** | check if the string is a hash of type algorithm.<br/><br/>Algorithm is one of `['md4', 'md5', 'sha1', 'sha256', 'sha384', 'sha512', 'ripemd128', 'ripemd160', 'tiger128', 'tiger160', 'tiger192', 'crc32', 'crc32b']`
**is_hexadecimal(str)** | check if the string is a hexadecimal number.
Expand Down
1 change: 1 addition & 0 deletions pyvalidator/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,4 @@
from pyvalidator.is_mailto_uri import is_mailto_uri
from pyvalidator.is_mime_type import is_mime_type
from pyvalidator.is_iso6391 import is_iso6391
from pyvalidator.is_freight_container_id import is_freight_container_id
34 changes: 34 additions & 0 deletions pyvalidator/is_freight_container_id.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import re
from .utils.assert_string import assert_string

isISO6346Str = re.compile(r'^[A-Z]{3}((U[0-9]{7})|([J,Z][0-9]{6,7}))$')
isDigit = re.compile(r'^[0-9]$')

def is_freight_container_id(input):
input = assert_string(input)
input = input.upper()

if not isISO6346Str.match(input):
return False

if len(input) == 11:
_sum = 0
for i in range(len(input) - 1):
if not isDigit.match(input[i]):
letterCode = ord(input[i]) - 55
if letterCode < 11:
convertedCode = letterCode
elif 11 <= letterCode <= 20:
convertedCode = 12 + (letterCode % 11)
elif 21 <= letterCode <= 30:
convertedCode = 23 + (letterCode % 21)
else:
convertedCode = 34 + (letterCode % 31)
_sum += convertedCode * (2 ** i)
else:
_sum += int(input[i]) * (2 ** i)

checkSumDigit = _sum % 11
return int(input[-1]) == checkSumDigit

return True
4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
readme = f.read()

MAJOR = 0
MINOR = 19
PATCH = 1
MINOR = 20
PATCH = 0

VERSION = '{}.{}.{}'.format(MAJOR, MINOR, PATCH)
DESCRIPTION = 'String validation and sanitization'
Expand Down
38 changes: 38 additions & 0 deletions test/test_is_freight_container_id.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import unittest
from pyvalidator.is_freight_container_id import is_freight_container_id
from . import print_test_ok

class TestIsFreightContainerId(unittest.TestCase):

def test_valid_ISO6346(self):
valid_codes = [
'HLXU2008419',
'TGHU7599330',
'ECMU4657496',
'MEDU6246078',
'YMLU2809976',
'MRKU0046221',
'EMCU3811879',
'OOLU8643084',
'HJCU1922713',
'QJRZ123456',
]
for code in valid_codes:
self.assertTrue(is_freight_container_id(code))
print_test_ok()

def test_invalid_ISO6346(self):
invalid_codes = [
'OOLU1922713',
'HJCU1922413',
'FCUI985619',
'ECMJ4657496',
'TBJA7176445',
'AFFU5962593',
]
for code in invalid_codes:
self.assertFalse(is_freight_container_id(code))
print_test_ok()

if __name__ == '__main__':
unittest.main()

0 comments on commit ffb23f7

Please sign in to comment.