Skip to content

Commit ffb23f7

Browse files
committed
feat: added is_freight_container_id validator
1 parent 5f08645 commit ffb23f7

File tree

5 files changed

+76
-2
lines changed

5 files changed

+76
-2
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ Validator | Description
7070
**is_even(str/int)** | checks if the input is an even number, it accepts either a string or an int.
7171
**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`.
7272
**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`).
73+
**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.
7374
**is_full_width(str)** | check if the string contains any full-width chars.
7475
**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']`
7576
**is_hexadecimal(str)** | check if the string is a hexadecimal number.

pyvalidator/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,4 @@
6666
from pyvalidator.is_mailto_uri import is_mailto_uri
6767
from pyvalidator.is_mime_type import is_mime_type
6868
from pyvalidator.is_iso6391 import is_iso6391
69+
from pyvalidator.is_freight_container_id import is_freight_container_id
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import re
2+
from .utils.assert_string import assert_string
3+
4+
isISO6346Str = re.compile(r'^[A-Z]{3}((U[0-9]{7})|([J,Z][0-9]{6,7}))$')
5+
isDigit = re.compile(r'^[0-9]$')
6+
7+
def is_freight_container_id(input):
8+
input = assert_string(input)
9+
input = input.upper()
10+
11+
if not isISO6346Str.match(input):
12+
return False
13+
14+
if len(input) == 11:
15+
_sum = 0
16+
for i in range(len(input) - 1):
17+
if not isDigit.match(input[i]):
18+
letterCode = ord(input[i]) - 55
19+
if letterCode < 11:
20+
convertedCode = letterCode
21+
elif 11 <= letterCode <= 20:
22+
convertedCode = 12 + (letterCode % 11)
23+
elif 21 <= letterCode <= 30:
24+
convertedCode = 23 + (letterCode % 21)
25+
else:
26+
convertedCode = 34 + (letterCode % 31)
27+
_sum += convertedCode * (2 ** i)
28+
else:
29+
_sum += int(input[i]) * (2 ** i)
30+
31+
checkSumDigit = _sum % 11
32+
return int(input[-1]) == checkSumDigit
33+
34+
return True

setup.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
readme = f.read()
55

66
MAJOR = 0
7-
MINOR = 19
8-
PATCH = 1
7+
MINOR = 20
8+
PATCH = 0
99

1010
VERSION = '{}.{}.{}'.format(MAJOR, MINOR, PATCH)
1111
DESCRIPTION = 'String validation and sanitization'

test/test_is_freight_container_id.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import unittest
2+
from pyvalidator.is_freight_container_id import is_freight_container_id
3+
from . import print_test_ok
4+
5+
class TestIsFreightContainerId(unittest.TestCase):
6+
7+
def test_valid_ISO6346(self):
8+
valid_codes = [
9+
'HLXU2008419',
10+
'TGHU7599330',
11+
'ECMU4657496',
12+
'MEDU6246078',
13+
'YMLU2809976',
14+
'MRKU0046221',
15+
'EMCU3811879',
16+
'OOLU8643084',
17+
'HJCU1922713',
18+
'QJRZ123456',
19+
]
20+
for code in valid_codes:
21+
self.assertTrue(is_freight_container_id(code))
22+
print_test_ok()
23+
24+
def test_invalid_ISO6346(self):
25+
invalid_codes = [
26+
'OOLU1922713',
27+
'HJCU1922413',
28+
'FCUI985619',
29+
'ECMJ4657496',
30+
'TBJA7176445',
31+
'AFFU5962593',
32+
]
33+
for code in invalid_codes:
34+
self.assertFalse(is_freight_container_id(code))
35+
print_test_ok()
36+
37+
if __name__ == '__main__':
38+
unittest.main()

0 commit comments

Comments
 (0)