checkdigit
Advanced tools
| # /usr/bin/env python | ||
| # This file is part of checkdigit. | ||
| # checkdigit is free software: you can redistribute it and/or modify | ||
| # it under the terms of the GNU General Public License as published by | ||
| # the Free Software Foundation, either version 3 of the License, or | ||
| # (at your option) any later version. | ||
| # checkdigit is distributed in the hope that it will be useful, | ||
| # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| # GNU General Public License for more details. | ||
| # You should have received a copy of the GNU General Public License | ||
| # along with checkdigit. If not, see <http://www.gnu.org/licenses/>. | ||
| """Cyclic Redundancy Check. | ||
| A block of binary as a form of data validation is appended to a bitstring. | ||
| This can be easily checked even by very simple circuitry, | ||
| and can also be used to correct some errors. | ||
| WARNING: THIS IS NOT A FAST IMPLEMENTATION OF CRC. | ||
| If you want a fast implementation look elsewhere. | ||
| """ | ||
| from checkdigit._data import cleanse | ||
| # WARNING: Data beginning with 0 must be as a string due to PEP 3127 | ||
| def calculate(data: str, polynomial: str, pad: str = "0") -> str: | ||
| """Adds a parity part onto the end of a block of data. | ||
| Args: | ||
| data: A string containing binary digits of any length | ||
| polynomial: A string of binary digits representing the polynomial being used | ||
| pad: "1" or "0" or nothing to be used to pad the data (defaults to 0) | ||
| Returns: | ||
| str: Check Value that should be appended to the stream | ||
| Examples: | ||
| >>> from checkdigit import crc | ||
| >>> crc.calculate("1010", "1011") | ||
| '011' | ||
| >>> crc.calculate("100110010100111101111101", "11010111101") | ||
| '0010001100' | ||
| """ | ||
| data = cleanse(data) | ||
| data += pad * (len(polynomial) - 1) | ||
| bitarray = list(data) | ||
| while len(bitarray) != len(polynomial) - 1: | ||
| for (bit, _) in enumerate(polynomial): | ||
| if polynomial[bit] == bitarray[bit]: | ||
| bitarray[bit] = "0" # XOR calculation | ||
| else: | ||
| bitarray[bit] = "1" | ||
| while bitarray[0] == "0" and len(bitarray) >= len(polynomial): | ||
| bitarray.pop(0) | ||
| return "".join(bitarray) | ||
| def validate(data: str, polynomial: str) -> bool: | ||
| """Validates whether the check digit matches a block of data. | ||
| Args: | ||
| data: A string containing binary digits including the check digit | ||
| polynomial: Polynomial to use | ||
| Returns: | ||
| bool: A boolean representing whether the data is valid or not | ||
| Examples: | ||
| >>> from checkdigit import crc | ||
| >>> crc.validate("1010101", "101") | ||
| True | ||
| >>> crc.validate("1000101", "101") | ||
| False | ||
| """ | ||
| data = cleanse(data) | ||
| # the principle of CRCs is that when done again but with the check digit | ||
| # appended if the data is fine it should all be 0s | ||
| return "0" * (len(polynomial) - 1) == calculate(data, polynomial, "") | ||
| def missing(data: str, polynomial: str) -> str: | ||
| """Calculates missing digits represented by a question mark. | ||
| Args: | ||
| data: A string containing a question mark representing a missing digit. | ||
| polynomial: What the polynomial that should be used is | ||
| Returns: | ||
| str: The missing binary digit | ||
| Examples: | ||
| >>> from checkdigit import crc | ||
| >>> crc.missing("?1111111101", "1101") | ||
| '1' | ||
| >>> crc.missing("10?110010100111?0?1111?10010?011?0", "11010111101") | ||
| '011000' | ||
| >>> # If there's more than one possible option | ||
| >>> crc.missing("?1111111001", "1101") | ||
| 'Invalid' | ||
| """ | ||
| solutions = [] | ||
| number = data.count("?") | ||
| if number == 0: | ||
| return "Invalid" # if there are no ? to replace the algorithm will not work | ||
| permutations = 2 ** number # number of different permutations that are possible | ||
| for permutation in range(permutations): | ||
| tocheck = data | ||
| replacement = bin(permutation)[2:].zfill( | ||
| number | ||
| ) # gives us a nice binary number | ||
| for bit in replacement: | ||
| tocheck = tocheck.replace("?", bit, 1) # only replaces one bit at a time | ||
| if validate(tocheck, polynomial): | ||
| solutions.append(replacement) | ||
| if len(solutions) == 2: | ||
| return "Invalid" | ||
| if len(solutions) == 1: | ||
| return solutions[0] | ||
| return "Invalid" |
+196
| .. image:: art/logo.png | ||
| :alt: checkdigit logo | ||
| :align: center | ||
| | | ||
| .. image:: https://img.shields.io/github/workflow/status/harens/checkdigit/Tests?logo=github&style=flat-square | ||
| :alt: GitHub Tests status | ||
| .. image:: https://img.shields.io/codecov/c/github/harens/checkdigit?logo=codecov&style=flat-square | ||
| :alt: Codecov | ||
| .. image:: https://img.shields.io/pypi/dm/checkdigit?logo=python&logoColor=white&style=flat-square | ||
| :alt: PyPi - Downloads | ||
| .. image:: https://img.shields.io/codefactor/grade/github/harens/checkdigit?logo=codefactor&style=flat-square | ||
| :alt: CodeFactor Grade | ||
| .. image:: https://img.shields.io/lgtm/grade/python/github/harens/checkdigit?logo=lgtm&style=flat-square | ||
| :alt: LGTM Grade | ||
| | | ||
| .. image:: art/demo.gif | ||
| :alt: checkdigit example gif | ||
| :align: center | ||
| **checkdigit** is a pure Python library built for identification numbers. | ||
| You want to validate a credit card number, or maybe even calculate a missing digit on an ISBN code? | ||
| We've got you covered š. | ||
| Want to know more? Check out the `API Reference and documentation <https://checkdigit.readthedocs.io/en/latest/reference.html>`_! | ||
| Installation | ||
| ------------ | ||
| `MacPorts <https://ports.macports.org/port/py-checkdigit/summary>`_ š | ||
| ************************************************************************* | ||
| .. code-block:: | ||
| sudo port install py-checkdigit | ||
| `PyPi <https://pypi.org/project/checkdigit/>`_ š | ||
| ************************************************** | ||
| .. code-block:: | ||
| pip install checkdigit | ||
| ⨠Features | ||
| ------------ | ||
| * `PEP 561 compatible <https://www.python.org/dev/peps/pep-0561>`_, with built in support for type checking. | ||
| * Capable of calculating missing digits or validating a block of data. | ||
| * Extensive in-code comments and docstrings to explain how it works behind the scenes. šŖ | ||
| ā Supported Formats | ||
| --------------------- | ||
| * Even and odd binary parity | ||
| * Bookland | ||
| * CRC (credit to `@sapieninja <https://github.com/sapieninja>`_) | ||
| * EAN-13 | ||
| * GS1 (credit to `@OtherBarry <https://github.com/OtherBarry>`_) | ||
| * ISBN-10 | ||
| * ISBN-13 | ||
| * Luhn | ||
| * UPC-A | ||
| For each of these formats, we provide functions to validate them and calculate missing digits. | ||
| Do you have any formats that you'd like to see supported? š¤ Feel free to raise an issue, | ||
| or even to send a pull request! | ||
| šØ Contributing | ||
| --------------- | ||
| - Issue Tracker: `<https://github.com/harens/checkdigit/issues>`_ | ||
| - Source Code: `<https://github.com/harens/checkdigit>`_ | ||
| Any change, big or small, that you think can help improve this project is more than welcome š. | ||
| As well as this, feel free to open an issue with any new suggestions or bug reports. Every contribution is appreciated. | ||
| š Setup | ||
| ********* | ||
| First, fork the project to your account. Then, run the following with your GitHub handle in place of | ||
| :code:`INSERT_GITHUB_NAME`: | ||
| .. code-block:: console | ||
| git clone https://github.com/INSERT_GITHUB_NAME/checkdigit | ||
| poetry install && poetry shell | ||
| pre-commit install | ||
| š Project structure | ||
| ******************** | ||
| .. | ||
| Credit for file structure: https://stackoverflow.com/a/38819161 | ||
| :: | ||
| checkdigit | ||
| āāā scripts | ||
| ā āāā format.sh | ||
| ā āāā tests.sh | ||
| āāā checkdigit | ||
| ā āāā gs1.py | ||
| ā āāā isbn.py | ||
| ā āāā luhn.py | ||
| ā āāā etc. | ||
| āāā tests | ||
| Each new format goes into a separate file which is named accordingly. Similar formats (e.g. ISBN-10 and ISBN-13) | ||
| should go in the same file. | ||
| Before submitting any new changes, please run the :code:`format.sh` and :code:`tests.sh` scripts beforehand. Thank you :) | ||
| š Building the Docs | ||
| ********************* | ||
| The documentation can be found in :code:`docs/source`. | ||
| We can use `sphinx-autobuild <https://github.com/executablebooks/sphinx-autobuild>`_ to continuously rebuild the docs when changes are made. | ||
| .. code-block:: console | ||
| sphinx-autobuild docs/source docs/_build/html | ||
| šŖ File structure | ||
| ***************** | ||
| Each of the Python files follow the same general format: | ||
| .. code-block:: python | ||
| # License + File docstring | ||
| from checkdigit._data import cleanse, convert | ||
| def calculate(data: str) -> str: | ||
| """Determines check digit. | ||
| Args: | ||
| data: A string of data missing a check digit | ||
| Returns: | ||
| str: The single missing check digit (not the whole block of data) | ||
| """ | ||
| # This helps to deal with user formatting inconsistencies | ||
| # e.g. spaces, hyphens, etc. | ||
| data = cleanse(data) | ||
| # Deals with 10 or 11 being the possible check digit | ||
| return convert(...) | ||
| def validate(data: str) -> bool: | ||
| """Validates a block of data from the check digit. | ||
| Args: | ||
| data: A string representing a full block of data | ||
| Returns: | ||
| bool: A boolean representing whether the data is valid or not | ||
| """ | ||
| data = cleanse(data) | ||
| # Remove the check digit and see if it matches | ||
| return calculate(data[:-1]) == data[-1] | ||
| def missing(data: str) -> str: | ||
| """Returns the missing digit from a block of data. | ||
| Args: | ||
| data: A string with a question mark in the place of a missing digit. | ||
| Returns: | ||
| A string representing the missing digit (not the whole block of data) | ||
| """ | ||
| data = cleanse(data) | ||
| return ... | ||
| For similar data formats, the names can be adjusted accordingly (e.g. :code:`validate10` for ISBN-10 and :code:`validate13` for ISBN-13). | ||
| š License | ||
| ----------- | ||
| This project is licensed under `GPL-3.0-or-later <https://github.com/harens/checkdigit/blob/master/LICENSE>`_. |
@@ -16,3 +16,3 @@ # /usr/bin/env python | ||
| """A check digit library for data validation. | ||
| """An easy-to-use check digit library for data validation. | ||
@@ -23,4 +23,4 @@ This Python library contains various functions relating to Luhn, ISBN, UPC and many other codes. | ||
| For more information, please look at the GitHub page for this library: | ||
| https://github.com/harens/checkdigit | ||
| https://checkdigit.rtfd.io/ | ||
| """ |
+11
-0
@@ -81,2 +81,13 @@ # /usr/bin/env python | ||
| Examples: | ||
| >>> from checkdigit import gs1 | ||
| >>> gs1.missing("?8945528") | ||
| '9' | ||
| >>> gs1.missing("992802?035392") | ||
| '2' | ||
| >>> gs1.missing("084085752492131?31") | ||
| '7' | ||
| >>> gs1.missing("846684302750007275") | ||
| 'Invalid' | ||
| """ | ||
@@ -83,0 +94,0 @@ data = cleanse(data) |
+70
-32
@@ -20,7 +20,4 @@ # /usr/bin/env python | ||
| For more information, please look at the wiki page for this module: | ||
| https://github.com/harens/checkdigit/wiki/š-ISBN | ||
| Note that the ISBN-13 functions can also be used for EAN-13 and Bookland codes. | ||
| Note that the ISBN-13 functions can also be used for EAN-13 and Bookland codes | ||
| """ | ||
@@ -41,11 +38,16 @@ | ||
| str: The check digit that was missing | ||
| Examples: | ||
| >>> from checkdigit import isbn | ||
| >>> isbn.calculate10("006196436") | ||
| '0' | ||
| >>> isbn.calculate10("043942089") | ||
| 'X' | ||
| """ | ||
| data = cleanse(data) | ||
| total_sum = 0 | ||
| multiply_counter = 10 | ||
| for item in data: | ||
| total_sum += int(item) * multiply_counter | ||
| multiply_counter -= 1 # Multiplies first digit by 10, second by 9... | ||
| check_digit = 11 - (total_sum % 11) | ||
| return convert(check_digit) | ||
| # Multiply first digit by 10, second by 9, ... and take the sum | ||
| total_sum = sum( | ||
| int(digit) * weight for digit, weight in zip(data, range(10, 0, -1)) | ||
| ) | ||
| return convert(11 - (total_sum % 11)) | ||
@@ -63,2 +65,10 @@ | ||
| Examples: | ||
| >>> from checkdigit import isbn | ||
| >>> isbn.validate10("1-56619-909-3") | ||
| True | ||
| >>> isbn.validate10("0198526636") | ||
| True | ||
| >>> isbn.validate10("423423") | ||
| False | ||
| """ | ||
@@ -78,16 +88,18 @@ data = cleanse(data) | ||
| str: The check digit that was missing | ||
| Examples: | ||
| >>> from checkdigit import isbn | ||
| >>> isbn.calculate13("978-1-86197-876") | ||
| '9' | ||
| >>> isbn.calculate13("012345678912") | ||
| '8' | ||
| """ | ||
| data = cleanse(data) | ||
| mod_number = 0 if barcode == "isbn" else 1 | ||
| total_sum = 0 | ||
| position_counter = 1 # 1 based indexing for data | ||
| for item in data: | ||
| digit = int(item) | ||
| if position_counter % 2 == mod_number: | ||
| total_sum += digit * 3 # Multiplies by 3 if position is even | ||
| else: | ||
| total_sum += digit | ||
| position_counter += 1 | ||
| final_value = 10 - (total_sum % 10) | ||
| return convert(final_value, barcode) | ||
| # ISBN weights is 1 for odd positions and 3 for even | ||
| # The opposite is true for upc | ||
| weights = (1, 3) * 6 if barcode == "isbn" else (3, 1) * 6 | ||
| # Multiply each digit by its weight | ||
| total_sum = sum(int(digit) * weight for digit, weight in zip(data, weights)) | ||
| # Return final check digit and type of barcode | ||
| return convert(10 - (total_sum % 10), barcode) | ||
@@ -104,2 +116,11 @@ | ||
| Examples: | ||
| >>> from checkdigit import isbn | ||
| >>> isbn.validate13("978-1-56619-909-4") | ||
| True | ||
| >>> isbn.validate13("0123456789128") | ||
| True | ||
| >>> isbn.validate13("1234") | ||
| False | ||
| """ | ||
@@ -111,3 +132,3 @@ data = cleanse(data) | ||
| def missing(data: str) -> str: | ||
| """Calculates a missing digit in an ISBN Code. | ||
| """Calculates a missing digit in an ISBN Code represented by a question mark. | ||
@@ -121,13 +142,30 @@ Args: | ||
| Examples: | ||
| >>> from checkdigit import isbn | ||
| >>> isbn.missing("15688?111X") | ||
| '1' | ||
| >>> isbn.missing("978186197876?") | ||
| '9' | ||
| >>> isbn.missing("023456789128") | ||
| 'Invalid' | ||
| """ | ||
| data = cleanse(data) | ||
| for poss_digit in range(11): # Brute Force the 11 options | ||
| option = convert(poss_digit) | ||
| # Depending on the size of the data, the relevant validating function | ||
| # tests it with the generated number | ||
| # If this fails, the next number is tried | ||
| if (len(data) == 10 and validate10(data.replace("?", option))) or ( | ||
| len(data) == 13 and validate13(data.replace("?", option)) | ||
| data_length = len(data) # ISBN-10 or 13 | ||
| # We already have an efficient method for the checkdigit | ||
| if data[-1] == "?": | ||
| # Remove question mark check digit | ||
| return calculate10(data[:-1]) if data_length == 10 else calculate13(data[:-1]) | ||
| # We've dealt with the check digit, so X can't be an option | ||
| # Brute force all the possible numbers (0-9 inclusive) | ||
| for option in (data.replace("?", str(i)) for i in range(10)): | ||
| # Validate the new option | ||
| if ( | ||
| data_length == 10 | ||
| and validate10(option) | ||
| or data_length == 13 | ||
| and validate13(option) | ||
| ): | ||
| return option | ||
| # Replace question mark with new value | ||
| return option[data.index("?")] | ||
| return "Invalid" |
+40
-19
@@ -21,8 +21,5 @@ # /usr/bin/env python | ||
| For more information, please look at the wiki page for this module: | ||
| https://github.com/harens/checkdigit/wiki/š³-Luhn | ||
| """ | ||
| from checkdigit._data import cleanse, convert | ||
| from checkdigit._data import cleanse | ||
@@ -41,19 +38,23 @@ # WARNING: Data beginning with 0 must be as a string due to PEP 3127 | ||
| Examples: | ||
| >>> from checkdigit import luhn | ||
| >>> luhn.calculate("53251309870224") | ||
| '3' | ||
| >>> luhn.calculate("950123440000") | ||
| '8' | ||
| """ | ||
| data = cleanse(data) | ||
| position_counter = 1 # 1-based indexing | ||
| total_sum = 0 | ||
| for item in data[::-1]: # Reverses String | ||
| digit = int(item) | ||
| if position_counter % 2: # If position number is odd with reversed string | ||
| add_value = digit * 2 | ||
| if add_value > 9: | ||
| for number in str(add_value): # Adds individual digits together | ||
| total_sum += int(number) | ||
| else: | ||
| total_sum += add_value | ||
| else: | ||
| total_sum += digit | ||
| position_counter += 1 | ||
| return convert(10 - (total_sum % 10), "luhn") | ||
| # Double every other digit, starting from the final digit backwards | ||
| # i.e. double 0th digit, 2nd, 4th, ... | ||
| double_digits = ( | ||
| int(element) if index % 2 else int(element) * 2 | ||
| for index, element in enumerate(data[::-1]) | ||
| ) | ||
| # For digits with more than one digit, sum the digits together | ||
| # The maximum is 9*2 = 18. This divmod method will work <100 | ||
| sum_digits = sum(sum(divmod(i, 10)) for i in double_digits) | ||
| # Mod 10 returns 0-9 (not 10 or 11) | ||
| # Hence convert method not required (faster to use str) | ||
| return str((sum_digits * 9) % 10) | ||
@@ -70,2 +71,13 @@ | ||
| Examples: | ||
| >>> from checkdigit import luhn | ||
| >>> luhn.validate("541756116585277") | ||
| True | ||
| >>> luhn.validate("79927398713") | ||
| True | ||
| >>> luhn.validate("49927398717") | ||
| False | ||
| >>> luhn.validate("1234567812345678") | ||
| False | ||
| """ | ||
@@ -88,2 +100,11 @@ data = cleanse(data) | ||
| Examples: | ||
| >>> from checkdigit import luhn | ||
| >>> luhn.missing("54175611658527?") | ||
| '7' | ||
| >>> luhn.missing("515853022?76176") | ||
| '1' | ||
| >>> luhn.missing("78369216316") | ||
| 'Invalid' | ||
| """ | ||
@@ -90,0 +111,0 @@ data = cleanse(data) |
+75
-7
@@ -20,5 +20,2 @@ # /usr/bin/env python | ||
| For more information, please look at the wiki page for this module: | ||
| https://github.com/harens/checkdigit/wiki/1%EF%B8%8Fā£-Parity-Bits | ||
| """ | ||
@@ -36,10 +33,81 @@ | ||
| data: A string containing binary digits | ||
| even: Whether to use even parity (otherwise uses odd parity) | ||
| even: Whether to use even or odd parity (defaults to even) | ||
| Returns: | ||
| str: The original data with the parity bit added to the end | ||
| str: The parity bit of the data | ||
| Examples: | ||
| >>> from checkdigit import parity | ||
| >>> # Even parity | ||
| >>> parity.calculate("0110") | ||
| '0' | ||
| >>> parity.calculate("01101") | ||
| '1' | ||
| >>> # Odd parity | ||
| >>> parity.calculate("01101", False) | ||
| '0' | ||
| >>> parity.calculate("0", False) | ||
| '1' | ||
| """ | ||
| data = cleanse(data) | ||
| if (even and not data.count("1") % 2) or (not even and data.count("1") % 2): | ||
| return data + "0" | ||
| return data + "1" | ||
| return "0" | ||
| return "1" | ||
| def validate(data: str, even: bool = True) -> bool: | ||
| """Validates whether the check digit matches a block of data. | ||
| Args: | ||
| data: A string containing binary digits | ||
| even: Whether to use even or odd parity (defaults to even) | ||
| Returns: | ||
| bool: A boolean representing whether the data is valid or not | ||
| Examples: | ||
| >>> from checkdigit import parity | ||
| >>> # Even parity | ||
| >>> parity.validate("01100") | ||
| True | ||
| >>> parity.validate("01101") | ||
| False | ||
| >>> # Odd parity | ||
| >>> parity.validate("01101", False) | ||
| True | ||
| >>> parity.validate("01100", False) | ||
| False | ||
| """ | ||
| data = cleanse(data) | ||
| return calculate(data[:-1], even) == data[-1] | ||
| def missing(data: str, even: bool = True) -> str: | ||
| """Calculates a missing digit represented by a question mark. | ||
| Args: | ||
| data: A string containing a question mark representing a missing digit. | ||
| even: Whether to use even or odd parity (defaults to even) | ||
| Returns: | ||
| str: The missing binary digit | ||
| Examples: | ||
| >>> from checkdigit import parity | ||
| >>> # Even parity | ||
| >>> parity.missing("01?00") | ||
| '1' | ||
| >>> parity.missing("01?100") | ||
| '0' | ||
| >>> # Odd parity | ||
| >>> parity.missing("01101?", False) | ||
| '0' | ||
| >>> parity.missing("010010?011", False) | ||
| '1' | ||
| """ | ||
| # Same principle as check digit (just not necessarily on the end) | ||
| return calculate(data.replace("?", ""), even) |
+15
-4
@@ -16,3 +16,3 @@ # /usr/bin/env python | ||
| """Parity Validation Functions. | ||
| """UPC Validation Functions. | ||
@@ -22,5 +22,2 @@ UPC-A codes are the main variant of Universal Product Codes. | ||
| For more information, please look at the wiki page for this module: | ||
| https://github.com/harens/checkdigit/wiki/š¦-UPC-A | ||
| """ | ||
@@ -47,2 +44,9 @@ | ||
| str: The missing check digit | ||
| Examples: | ||
| >>> from checkdigit import upc | ||
| >>> upc.calculate("17593487596") | ||
| '0' | ||
| >>> upc.calculate("73799324006") | ||
| '8' | ||
| """ | ||
@@ -60,3 +64,10 @@ return isbn.calculate13(data, "upc") | ||
| bool: A boolean representing whether the check digit validates the data or not | ||
| Examples: | ||
| >>> from checkdigit import upc | ||
| >>> upc.validate("672792398018") | ||
| True | ||
| >>> upc.validate("672792398017") | ||
| False | ||
| """ | ||
| return calculate(data[:-1]) == data[-1] |
+181
-43
| Metadata-Version: 2.1 | ||
| Name: checkdigit | ||
| Version: 0.1.2 | ||
| Version: 0.1.3 | ||
| Summary: A check digit library for data validation | ||
| Home-page: https://github.com/harens/checkdigit | ||
| Home-page: https://checkdigit.readthedocs.io | ||
| License: GPL-3.0-or-later | ||
@@ -12,3 +12,3 @@ Keywords: Check Digits,Validation,ISBN | ||
| Maintainer-email: harensdeveloper@gmail.com | ||
| Requires-Python: >=3.6,<4.0 | ||
| Requires-Python: >=3.6.1,<4.0 | ||
| Classifier: Intended Audience :: Developers | ||
@@ -19,3 +19,2 @@ Classifier: License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+) | ||
| Classifier: Programming Language :: Python :: 3 | ||
| Classifier: Programming Language :: Python :: 3.6 | ||
| Classifier: Programming Language :: Python :: 3.7 | ||
@@ -26,63 +25,202 @@ Classifier: Programming Language :: Python :: 3.8 | ||
| Project-URL: Bug Tracker, https://github.com/harens/checkdigit/issues | ||
| Project-URL: Documentation, https://github.com/harens/checkdigit/wiki | ||
| Project-URL: Documentation, https://checkdigit.readthedocs.io | ||
| Project-URL: Repository, https://github.com/harens/checkdigit | ||
| Description-Content-Type: text/markdown | ||
| Description-Content-Type: text/x-rst | ||
| # checkdigit | ||
| .. image:: art/logo.png | ||
| :alt: checkdigit logo | ||
| :align: center | ||
| A check digit library for data validation. | ||
| | Test Status | [](https://github.com/harens/checkdigit/actions) [](https://codecov.io/gh/harens/checkdigit) | | ||
| |:--|:--| | ||
| | __Version Info__ | [](https://pypi.org/project/checkdigit/) [](https://github.com/harens/checkdigit/releases) [](https://pypi.org/project/checkdigit/) | | ||
| | __Code Analysis__ |[](https://codeclimate.com/github/harens/checkdigit) [](https://www.codefactor.io/repository/github/harens/checkdigit) [](https://lgtm.com/projects/g/harens/checkdigit/)| | ||
| | | ||
| ## šØ Installation | ||
| .. image:: https://img.shields.io/github/workflow/status/harens/checkdigit/Tests?logo=github&style=flat-square | ||
| :alt: GitHub Tests status | ||
| ```shell | ||
| pip install checkdigit | ||
| ``` | ||
| .. image:: https://img.shields.io/codecov/c/github/harens/checkdigit?logo=codecov&style=flat-square | ||
| :alt: Codecov | ||
| Or download the project [here](https://github.com/harens/checkdigit/archive/master.zip). | ||
| .. image:: https://img.shields.io/pypi/dm/checkdigit?logo=python&logoColor=white&style=flat-square | ||
| :alt: PyPi - Downloads | ||
| ## ⨠Features | ||
| .. image:: https://img.shields.io/codefactor/grade/github/harens/checkdigit?logo=codefactor&style=flat-square | ||
| :alt: CodeFactor Grade | ||
| * Contains various functions relating to __Luhn, ISBN, UPC and many other codes__. | ||
| * __[PEP 561 compatible](https://www.python.org/dev/peps/pep-0561)__, with built in support for type checking. | ||
| * Extensive __in-code comments and docstrings__ to explain how the functions work. | ||
| * Written in __pure Python__ with __no dependencies__ required to run the program. | ||
| .. image:: https://img.shields.io/lgtm/grade/python/github/harens/checkdigit?logo=lgtm&style=flat-square | ||
| :alt: LGTM Grade | ||
| Check out the [documentation](https://github.com/harens/checkdigit/wiki) for more details on how to use the library. | ||
| | | ||
| ## šļø Contributing | ||
| .. image:: art/demo.gif | ||
| :alt: checkdigit example gif | ||
| :align: center | ||
| **checkdigit** is a pure Python library built for identification numbers. | ||
| You want to validate a credit card number, or maybe even calculate a missing digit on an ISBN code? | ||
| We've got you covered š. | ||
| Want to know more? Check out the `API Reference and documentation <https://checkdigit.readthedocs.io/en/latest/reference.html>`_! | ||
| Installation | ||
| ------------ | ||
| `MacPorts <https://ports.macports.org/port/py-checkdigit/summary>`_ š | ||
| ************************************************************************* | ||
| .. code-block:: | ||
| sudo port install py-checkdigit | ||
| `PyPi <https://pypi.org/project/checkdigit/>`_ š | ||
| ************************************************** | ||
| .. code-block:: | ||
| pip install checkdigit | ||
| ⨠Features | ||
| ------------ | ||
| * `PEP 561 compatible <https://www.python.org/dev/peps/pep-0561>`_, with built in support for type checking. | ||
| * Capable of calculating missing digits or validating a block of data. | ||
| * Extensive in-code comments and docstrings to explain how it works behind the scenes. šŖ | ||
| ā Supported Formats | ||
| --------------------- | ||
| * Even and odd binary parity | ||
| * Bookland | ||
| * CRC (credit to `@sapieninja <https://github.com/sapieninja>`_) | ||
| * EAN-13 | ||
| * GS1 (credit to `@OtherBarry <https://github.com/OtherBarry>`_) | ||
| * ISBN-10 | ||
| * ISBN-13 | ||
| * Luhn | ||
| * UPC-A | ||
| For each of these formats, we provide functions to validate them and calculate missing digits. | ||
| Do you have any formats that you'd like to see supported? š¤ Feel free to raise an issue, | ||
| or even to send a pull request! | ||
| šØ Contributing | ||
| --------------- | ||
| - Issue Tracker: `<https://github.com/harens/checkdigit/issues>`_ | ||
| - Source Code: `<https://github.com/harens/checkdigit>`_ | ||
| Any change, big or small, that you think can help improve this project is more than welcome š. | ||
| As well as this, feel free to open an issue with any new suggestions or bug reports. Every contribution is valued. | ||
| As well as this, feel free to open an issue with any new suggestions or bug reports. Every contribution is appreciated. | ||
| For smaller tasks (that are still really appreciated š), be sure to check the [good first issue](https://github.com/harens/checkdigit/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) tag. | ||
| š Setup | ||
| ********* | ||
| ## š» Setup | ||
| First, fork the project to your account. Then, run the following with your GitHub handle in place of | ||
| :code:`INSERT_GITHUB_NAME`: | ||
| Clone the project and install the dev dependencies: | ||
| .. code-block:: console | ||
| ```shell | ||
| git clone https://github.com/harens/checkdigit | ||
| cd checkdigit | ||
| poetry install | ||
| ``` | ||
| git clone https://github.com/INSERT_GITHUB_NAME/checkdigit | ||
| poetry install && poetry shell | ||
| pre-commit install | ||
| If you want to send a PR, please run the following: | ||
| š Project structure | ||
| ******************** | ||
| ```bash | ||
| bash ./scripts/format.sh # Format files | ||
| bash ./scripts/tests.sh # Run tests | ||
| .. | ||
| Credit for file structure: https://stackoverflow.com/a/38819161 | ||
| # NB shellcheck is not installed by poetry | ||
| shellcheck scripts/*.sh | ||
| ``` | ||
| :: | ||
| ## š License | ||
| checkdigit | ||
| āāā scripts | ||
| ā āāā format.sh | ||
| ā āāā tests.sh | ||
| āāā checkdigit | ||
| ā āāā gs1.py | ||
| ā āāā isbn.py | ||
| ā āāā luhn.py | ||
| ā āāā etc. | ||
| āāā tests | ||
| This project is licensed under [GPL-3.0-or-later](https://github.com/harens/checkdigit/blob/master/LICENSE). | ||
| Each new format goes into a separate file which is named accordingly. Similar formats (e.g. ISBN-10 and ISBN-13) | ||
| should go in the same file. | ||
| Before submitting any new changes, please run the :code:`format.sh` and :code:`tests.sh` scripts beforehand. Thank you :) | ||
| š Building the Docs | ||
| ********************* | ||
| The documentation can be found in :code:`docs/source`. | ||
| We can use `sphinx-autobuild <https://github.com/executablebooks/sphinx-autobuild>`_ to continuously rebuild the docs when changes are made. | ||
| .. code-block:: console | ||
| sphinx-autobuild docs/source docs/_build/html | ||
| šŖ File structure | ||
| ***************** | ||
| Each of the Python files follow the same general format: | ||
| .. code-block:: python | ||
| # License + File docstring | ||
| from checkdigit._data import cleanse, convert | ||
| def calculate(data: str) -> str: | ||
| """Determines check digit. | ||
| Args: | ||
| data: A string of data missing a check digit | ||
| Returns: | ||
| str: The single missing check digit (not the whole block of data) | ||
| """ | ||
| # This helps to deal with user formatting inconsistencies | ||
| # e.g. spaces, hyphens, etc. | ||
| data = cleanse(data) | ||
| # Deals with 10 or 11 being the possible check digit | ||
| return convert(...) | ||
| def validate(data: str) -> bool: | ||
| """Validates a block of data from the check digit. | ||
| Args: | ||
| data: A string representing a full block of data | ||
| Returns: | ||
| bool: A boolean representing whether the data is valid or not | ||
| """ | ||
| data = cleanse(data) | ||
| # Remove the check digit and see if it matches | ||
| return calculate(data[:-1]) == data[-1] | ||
| def missing(data: str) -> str: | ||
| """Returns the missing digit from a block of data. | ||
| Args: | ||
| data: A string with a question mark in the place of a missing digit. | ||
| Returns: | ||
| A string representing the missing digit (not the whole block of data) | ||
| """ | ||
| data = cleanse(data) | ||
| return ... | ||
| For similar data formats, the names can be adjusted accordingly (e.g. :code:`validate10` for ISBN-10 and :code:`validate13` for ISBN-13). | ||
| š License | ||
| ----------- | ||
| This project is licensed under `GPL-3.0-or-later <https://github.com/harens/checkdigit/blob/master/LICENSE>`_. | ||
+13
-6
| [tool.poetry] | ||
| name = "checkdigit" | ||
| version = "0.1.2" | ||
| version = "0.1.3" | ||
| description = "A check digit library for data validation" | ||
| authors = ["harens <harensdeveloper@gmail.com>"] | ||
| maintainers = ["harens <harensdeveloper@gmail.com>"] | ||
| readme = "README.md" | ||
| readme = "PYPIREADME.rst" | ||
| license = "GPL-3.0-or-later" | ||
@@ -18,5 +18,5 @@ include = ["checkdigit/py.typed"] | ||
| homepage = "https://github.com/harens/checkdigit" | ||
| homepage = "https://checkdigit.readthedocs.io" | ||
| repository = "https://github.com/harens/checkdigit" | ||
| documentation = "https://github.com/harens/checkdigit/wiki" | ||
| documentation = "https://checkdigit.readthedocs.io" | ||
@@ -27,3 +27,3 @@ [tool.poetry.urls] | ||
| [tool.poetry.dependencies] | ||
| python = "^3.6" | ||
| python = ">=3.6.1,<4.0" | ||
@@ -36,4 +36,11 @@ [tool.poetry.dev-dependencies] | ||
| isort = "^5.8.0" | ||
| pydocstyle = "^6.0.0" | ||
| pydocstyle = "^6.1.1" | ||
| coverage = "^5.5" | ||
| pre-commit = "^2.12.1" | ||
| pyupgrade = "^2.17.0" | ||
| Sphinx = "^4.0.1" | ||
| sphinx-autobuild = "^2021.3.14" | ||
| pytest = "^6.2.4" | ||
| pytest-cov = "^2.12.0" | ||
| readme-renderer = "^29.0" | ||
@@ -40,0 +47,0 @@ [tool.coverage.run] |
+4
-4
@@ -12,5 +12,5 @@ # -*- coding: utf-8 -*- | ||
| 'name': 'checkdigit', | ||
| 'version': '0.1.2', | ||
| 'version': '0.1.3', | ||
| 'description': 'A check digit library for data validation', | ||
| 'long_description': '# checkdigit\n\nA check digit library for data validation.\n \n| Test Status | [](https://github.com/harens/checkdigit/actions) [](https://codecov.io/gh/harens/checkdigit) |\n|:--|:--|\n| __Version Info__ | [](https://pypi.org/project/checkdigit/) [](https://github.com/harens/checkdigit/releases) [](https://pypi.org/project/checkdigit/) |\n| __Code Analysis__ |[](https://codeclimate.com/github/harens/checkdigit) [](https://www.codefactor.io/repository/github/harens/checkdigit) [](https://lgtm.com/projects/g/harens/checkdigit/)|\n\n## šØ Installation\n\n```shell\npip install checkdigit\n```\n\nOr download the project [here](https://github.com/harens/checkdigit/archive/master.zip).\n\n## ⨠Features\n\n* Contains various functions relating to __Luhn, ISBN, UPC and many other codes__.\n* __[PEP 561 compatible](https://www.python.org/dev/peps/pep-0561)__, with built in support for type checking.\n* Extensive __in-code comments and docstrings__ to explain how the functions work.\n* Written in __pure Python__ with __no dependencies__ required to run the program.\n\nCheck out the [documentation](https://github.com/harens/checkdigit/wiki) for more details on how to use the library.\n\n## šļø Contributing\n\nAny change, big or small, that you think can help improve this project is more than welcome š.\n\nAs well as this, feel free to open an issue with any new suggestions or bug reports. Every contribution is valued.\n\nFor smaller tasks (that are still really appreciated š), be sure to check the [good first issue](https://github.com/harens/checkdigit/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) tag.\n\n## š» Setup\n\nClone the project and install the dev dependencies:\n\n```shell\ngit clone https://github.com/harens/checkdigit\ncd checkdigit\npoetry install\n```\n\nIf you want to send a PR, please run the following:\n\n```bash\nbash ./scripts/format.sh # Format files\nbash ./scripts/tests.sh # Run tests\n\n# NB shellcheck is not installed by poetry\nshellcheck scripts/*.sh\n```\n\n## š License\n\nThis project is licensed under [GPL-3.0-or-later](https://github.com/harens/checkdigit/blob/master/LICENSE).\n', | ||
| 'long_description': '.. image:: art/logo.png\n :alt: checkdigit logo\n :align: center\n\n|\n\n.. image:: https://img.shields.io/github/workflow/status/harens/checkdigit/Tests?logo=github&style=flat-square\n :alt: GitHub Tests status\n\n.. image:: https://img.shields.io/codecov/c/github/harens/checkdigit?logo=codecov&style=flat-square\n :alt: Codecov\n\n.. image:: https://img.shields.io/pypi/dm/checkdigit?logo=python&logoColor=white&style=flat-square\n :alt: PyPi - Downloads\n\n.. image:: https://img.shields.io/codefactor/grade/github/harens/checkdigit?logo=codefactor&style=flat-square\n :alt: CodeFactor Grade\n\n.. image:: https://img.shields.io/lgtm/grade/python/github/harens/checkdigit?logo=lgtm&style=flat-square\n :alt: LGTM Grade\n\n|\n\n.. image:: art/demo.gif\n :alt: checkdigit example gif\n :align: center\n\n**checkdigit** is a pure Python library built for identification numbers.\nYou want to validate a credit card number, or maybe even calculate a missing digit on an ISBN code?\nWe\'ve got you covered š.\n\nWant to know more? Check out the `API Reference and documentation <https://checkdigit.readthedocs.io/en/latest/reference.html>`_!\n\nInstallation\n------------\n\n`MacPorts <https://ports.macports.org/port/py-checkdigit/summary>`_ š\n*************************************************************************\n\n.. code-block::\n\n sudo port install py-checkdigit\n\n`PyPi <https://pypi.org/project/checkdigit/>`_ š\n**************************************************\n\n.. code-block::\n\n pip install checkdigit\n\n⨠Features\n------------\n\n* `PEP 561 compatible <https://www.python.org/dev/peps/pep-0561>`_, with built in support for type checking.\n* Capable of calculating missing digits or validating a block of data.\n* Extensive in-code comments and docstrings to explain how it works behind the scenes. \U0001fa84\n\nā Supported Formats\n---------------------\n\n* Even and odd binary parity\n* Bookland\n* CRC (credit to `@sapieninja <https://github.com/sapieninja>`_)\n* EAN-13\n* GS1 (credit to `@OtherBarry <https://github.com/OtherBarry>`_)\n* ISBN-10\n* ISBN-13\n* Luhn\n* UPC-A\n\nFor each of these formats, we provide functions to validate them and calculate missing digits.\n\nDo you have any formats that you\'d like to see supported? š¤ Feel free to raise an issue,\nor even to send a pull request!\n\nšØ Contributing\n---------------\n\n- Issue Tracker: `<https://github.com/harens/checkdigit/issues>`_\n- Source Code: `<https://github.com/harens/checkdigit>`_\n\nAny change, big or small, that you think can help improve this project is more than welcome š.\n\nAs well as this, feel free to open an issue with any new suggestions or bug reports. Every contribution is appreciated.\n\nš Setup\n*********\n\nFirst, fork the project to your account. Then, run the following with your GitHub handle in place of\n:code:`INSERT_GITHUB_NAME`:\n\n.. code-block:: console\n\n git clone https://github.com/INSERT_GITHUB_NAME/checkdigit\n poetry install && poetry shell\n pre-commit install\n \n\nš Project structure\n********************\n\n..\n Credit for file structure: https://stackoverflow.com/a/38819161\n\n::\n\n checkdigit\n āāā scripts\n ā āāā format.sh\n ā āāā tests.sh\n āāā checkdigit\n ā āāā gs1.py\n ā āāā isbn.py\n ā āāā luhn.py\n ā āāā etc.\n āāā tests\n\nEach new format goes into a separate file which is named accordingly. Similar formats (e.g. ISBN-10 and ISBN-13)\nshould go in the same file.\n\nBefore submitting any new changes, please run the :code:`format.sh` and :code:`tests.sh` scripts beforehand. Thank you :)\n\nš Building the Docs\n*********************\n\nThe documentation can be found in :code:`docs/source`.\n\nWe can use `sphinx-autobuild <https://github.com/executablebooks/sphinx-autobuild>`_ to continuously rebuild the docs when changes are made.\n\n.. code-block:: console\n\n sphinx-autobuild docs/source docs/_build/html\n\nšŖ File structure\n*****************\n\nEach of the Python files follow the same general format:\n\n.. code-block:: python\n\n # License + File docstring\n\n from checkdigit._data import cleanse, convert\n\n\n def calculate(data: str) -> str:\n """Determines check digit.\n\n Args:\n data: A string of data missing a check digit\n\n Returns:\n str: The single missing check digit (not the whole block of data)\n """\n # This helps to deal with user formatting inconsistencies\n # e.g. spaces, hyphens, etc.\n data = cleanse(data)\n\n # Deals with 10 or 11 being the possible check digit\n return convert(...)\n\n\n def validate(data: str) -> bool:\n """Validates a block of data from the check digit.\n\n Args:\n data: A string representing a full block of data\n\n Returns:\n bool: A boolean representing whether the data is valid or not\n """\n data = cleanse(data)\n\n # Remove the check digit and see if it matches\n return calculate(data[:-1]) == data[-1]\n\n\n def missing(data: str) -> str:\n """Returns the missing digit from a block of data.\n\n Args:\n data: A string with a question mark in the place of a missing digit.\n\n Returns:\n A string representing the missing digit (not the whole block of data)\n """\n data = cleanse(data)\n\n return ...\n\nFor similar data formats, the names can be adjusted accordingly (e.g. :code:`validate10` for ISBN-10 and :code:`validate13` for ISBN-13).\n\nš License\n-----------\n\nThis project is licensed under `GPL-3.0-or-later <https://github.com/harens/checkdigit/blob/master/LICENSE>`_.\n', | ||
| 'author': 'harens', | ||
@@ -20,6 +20,6 @@ 'author_email': 'harensdeveloper@gmail.com', | ||
| 'maintainer_email': 'harensdeveloper@gmail.com', | ||
| 'url': 'https://github.com/harens/checkdigit', | ||
| 'url': 'https://checkdigit.readthedocs.io', | ||
| 'packages': packages, | ||
| 'package_data': package_data, | ||
| 'python_requires': '>=3.6,<4.0', | ||
| 'python_requires': '>=3.6.1,<4.0', | ||
| } | ||
@@ -26,0 +26,0 @@ |
-57
| # checkdigit | ||
| A check digit library for data validation. | ||
| | Test Status | [](https://github.com/harens/checkdigit/actions) [](https://codecov.io/gh/harens/checkdigit) | | ||
| |:--|:--| | ||
| | __Version Info__ | [](https://pypi.org/project/checkdigit/) [](https://github.com/harens/checkdigit/releases) [](https://pypi.org/project/checkdigit/) | | ||
| | __Code Analysis__ |[](https://codeclimate.com/github/harens/checkdigit) [](https://www.codefactor.io/repository/github/harens/checkdigit) [](https://lgtm.com/projects/g/harens/checkdigit/)| | ||
| ## šØ Installation | ||
| ```shell | ||
| pip install checkdigit | ||
| ``` | ||
| Or download the project [here](https://github.com/harens/checkdigit/archive/master.zip). | ||
| ## ⨠Features | ||
| * Contains various functions relating to __Luhn, ISBN, UPC and many other codes__. | ||
| * __[PEP 561 compatible](https://www.python.org/dev/peps/pep-0561)__, with built in support for type checking. | ||
| * Extensive __in-code comments and docstrings__ to explain how the functions work. | ||
| * Written in __pure Python__ with __no dependencies__ required to run the program. | ||
| Check out the [documentation](https://github.com/harens/checkdigit/wiki) for more details on how to use the library. | ||
| ## šļø Contributing | ||
| Any change, big or small, that you think can help improve this project is more than welcome š. | ||
| As well as this, feel free to open an issue with any new suggestions or bug reports. Every contribution is valued. | ||
| For smaller tasks (that are still really appreciated š), be sure to check the [good first issue](https://github.com/harens/checkdigit/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) tag. | ||
| ## š» Setup | ||
| Clone the project and install the dev dependencies: | ||
| ```shell | ||
| git clone https://github.com/harens/checkdigit | ||
| cd checkdigit | ||
| poetry install | ||
| ``` | ||
| If you want to send a PR, please run the following: | ||
| ```bash | ||
| bash ./scripts/format.sh # Format files | ||
| bash ./scripts/tests.sh # Run tests | ||
| # NB shellcheck is not installed by poetry | ||
| shellcheck scripts/*.sh | ||
| ``` | ||
| ## š License | ||
| This project is licensed under [GPL-3.0-or-later](https://github.com/harens/checkdigit/blob/master/LICENSE). |
Alert delta unavailable
Currently unable to show alert delta for PyPI packages.
78648
26.1%14
7.69%608
64.32%