Commit 9f9d74da authored by luz's avatar luz

p44utils: added gtinCheckDigit() routine to validate/generate GTIN check digit

parent 45f70b33
...@@ -271,6 +271,24 @@ void p44::splitHost(const char *aHostSpec, string *aHostName, uint16_t *aPortNum ...@@ -271,6 +271,24 @@ void p44::splitHost(const char *aHostSpec, string *aHostName, uint16_t *aPortNum
} }
int p44::gtinCheckDigit(uint64_t aGtin)
{
// 64bit in decimal has max 20 digits (largest known to me GTIN-like number, the SSCC, has 17 digits)
// mod10 algorithm is:
// - sum of digits*3 at odd digit positions (least significant=rightmost=1=odd) + sum of digits at even positions.
// - check digit is the value to add to sum to get an even multiple of 10
int sum = 0;
int oldcheck = aGtin % 10; // current check digit as found in aGtin
for (int i=0; i<20; i++) {
aGtin /= 10;
int dig = aGtin % 10;
sum += ((i&1)==0 ? 3 : 1) * dig;
}
int newcheck = sum%10;
if (newcheck>0) newcheck = 10-newcheck; // difference to next multiple of 10 is checksum
return newcheck-oldcheck;
}
string p44::hexToBinaryString(const char *aHexString) string p44::hexToBinaryString(const char *aHexString)
{ {
......
...@@ -93,7 +93,6 @@ namespace p44 { ...@@ -93,7 +93,6 @@ namespace p44 {
/// @param aPasswd if not NULL, returns password, empty string if none /// @param aPasswd if not NULL, returns password, empty string if none
void splitURL(const char *aURI, string *aProtocol, string *aHost, string *aDoc, string *aUser=NULL, string *aPasswd=NULL); void splitURL(const char *aURI, string *aProtocol, string *aHost, string *aDoc, string *aUser=NULL, string *aPasswd=NULL);
/// split host specification into hostname and port /// split host specification into hostname and port
/// @param aHostSpec a host specification in the host[:port] format /// @param aHostSpec a host specification in the host[:port] format
/// @param aHostName if not NULL, returns the host name/IP address, empty string if none /// @param aHostName if not NULL, returns the host name/IP address, empty string if none
...@@ -101,6 +100,15 @@ namespace p44 { ...@@ -101,6 +100,15 @@ namespace p44 {
/// (such that variable passed can be initialized with the default port to use beforehand) /// (such that variable passed can be initialized with the default port to use beforehand)
void splitHost(const char *aHostSpec, string *aHostName, uint16_t *aPortNumber); void splitHost(const char *aHostSpec, string *aHostName, uint16_t *aPortNumber);
/// Verify or calculate GTIN check digit
/// @param aGtin full GTIN, including possibly inaccurate check digit
/// @return value to add to aGtin to make it a valid GTIN (-9..9)
/// @note
/// - if you want to check the GTIN, check for a result==0
/// - if you want to calculate the check digit, supply aGTIN with last digit 0
/// - if you want to make a GTIN valid, just add the result to aGtin
int gtinCheckDigit(uint64_t aGtin);
/// hex string to binary string conversion /// hex string to binary string conversion
/// @param aHexString string in hex notation /// @param aHexString string in hex notation
/// @return binary string /// @return binary string
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment