[utils] implement Verhoeff checksum calculation and validation (#9966)

This commit adds `Utils::VerhoeffChecksum` class along with public OT
APIs and related CLI commands for Verhoeff checksum calculation and
validation. Unit test `test_checksum` is updated to test the new
module.
This commit is contained in:
Abtin Keshavarzian
2024-04-08 17:11:43 -07:00
committed by GitHub
parent 8212acd133
commit 5c6b8328bc
14 changed files with 575 additions and 1 deletions
+1
View File
@@ -154,6 +154,7 @@
* @}
*
* @defgroup api-sntp SNTP
* @defgroup api-verhoeff-checksum Verhoeff Checksum
*
* @}
*
+1
View File
@@ -249,6 +249,7 @@ ot_option(OT_TX_BEACON_PAYLOAD OPENTHREAD_CONFIG_MAC_OUTGOING_BEACON_PAYLOAD_ENA
ot_option(OT_TX_QUEUE_STATS OPENTHREAD_CONFIG_TX_QUEUE_STATISTICS_ENABLE "tx queue statistics")
ot_option(OT_UDP_FORWARD OPENTHREAD_CONFIG_UDP_FORWARD_ENABLE "UDP forward")
ot_option(OT_UPTIME OPENTHREAD_CONFIG_UPTIME_ENABLE "uptime")
ot_option(OT_VERHOEFF_CHECKSUM OPENTHREAD_CONFIG_VERHOEFF_CHECKSUM_ENABLE "verhoeff checksum")
option(OT_DOC "build OpenThread documentation")
message(STATUS "- - - - - - - - - - - - - - - - ")
+1
View File
@@ -125,6 +125,7 @@ source_set("openthread") {
"thread_ftd.h",
"trel.h",
"udp.h",
"verhoeff_checksum.h",
]
public_deps = [ ":openthread_config" ]
+1 -1
View File
@@ -53,7 +53,7 @@ extern "C" {
* @note This number versions both OpenThread platform and user APIs.
*
*/
#define OPENTHREAD_API_VERSION (402)
#define OPENTHREAD_API_VERSION (403)
/**
* @addtogroup api-instance
+101
View File
@@ -0,0 +1,101 @@
/*
* Copyright (c) 2024, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* @brief
* This file defines APIs for Verhoeff checksum calculation and validation.
*/
#ifndef OPENTHREAD_VERHOEFF_CHECKSUM_H_
#define OPENTHREAD_VERHOEFF_CHECKSUM_H_
#include <openthread/error.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @addtogroup api-verhoeff-checksum
*
* @brief
* This module includes functions for Verhoeff checksum calculation and validation.
*
* The functions in this module are available when `OPENTHREAD_CONFIG_VERHOEFF_CHECKSUM_ENABLE` is enabled.
*
* @{
*
*/
/**
* Specifies the maximum length of decimal string input in `otVerhoeffChecksum` functions.
*
*/
#define OT_VERHOEFF_CHECKSUM_MAX_STRING_LENGTH 128
/**
* Calculates the Verhoeff checksum for a given decimal string.
*
* Requires `OPENTHREAD_CONFIG_VERHOEFF_CHECKSUM_ENABLE`.
*
* @param[in] aDecimalString The string containing decimal digits.
* @param[out] aChecksum Pointer to a `char` to return the calculated checksum.
*
* @retval OT_ERROR_NONE Successfully calculated the checksum, @p aChecksum is updated.
* @retval OT_ERROR_INVALID_ARGS The @p aDecimalString is not valid, i.e. it either contains chars other than
* ['0'-'9'], or is longer than `OT_VERHOEFF_CHECKSUM_MAX_STRING_LENGTH`.
*
*/
otError otVerhoeffChecksumCalculate(const char *aDecimalString, char *aChecksum);
/**
* Validates the Verhoeff checksum for a given decimal string.
*
* Requires `OPENTHREAD_CONFIG_VERHOEFF_CHECKSUM_ENABLE`.
*
* @param[in] aDecimalString The string containing decimal digits (last char is treated as checksum).
*
* @retval OT_ERROR_NONE Successfully validated the checksum in @p aDecimalString.
* @retval OT_ERROR_FAILED Checksum validation failed.
* @retval OT_ERROR_INVALID_ARGS The @p aDecimalString is not valid, i.e. it either contains chars other than
* ['0'-'9'], or is longer than `OT_VERHOEFF_CHECKSUM_MAX_STRING_LENGTH`.
*
*/
otError otVerhoeffChecksumValidate(const char *aDecimalString);
/**
* @}
*
*/
#ifdef __cplusplus
} // extern "C"
#endif
#endif // OPENTHREAD_VERHOEFF_CHECKSUM_H_
+30
View File
@@ -130,6 +130,7 @@ Done
- [unsecureport](#unsecureport-add-port)
- [uptime](#uptime)
- [vendor](#vendor-name)
- [verhoeff](#verhoeff-calculate)
- [version](#version)
## OpenThread Command Details
@@ -3964,6 +3965,35 @@ Set the vendor SW version (requires `OPENTHREAD_CONFIG_NET_DIAG_VENDOR_INFO_SET_
Done
```
### verhoeff calculate
Calculates the Verhoeff checksum for a given decimal string.
Requires `OPENTHREAD_CONFIG_VERHOEFF_CHECKSUM_ENABLE`.
The input string MUST consist of characters in `['0'-'9']`.
```bash
> verhoeff calculate 30731842
1
Done
```
### verhoeff validate
Validates the Verhoeff checksum for a given decimal string.
Requires `OPENTHREAD_CONFIG_VERHOEFF_CHECKSUM_ENABLE`.
The input string MUST consist of characters in `['0'-'9']`. The last digit is treated as checksum.
```bash
> verhoeff validate 307318421
Done
> verhoeff validate 307318425
Error 1: Failed
```
### version
Print the build version information.
+55
View File
@@ -45,6 +45,7 @@
#include <openthread/logging.h>
#include <openthread/ncp.h>
#include <openthread/thread.h>
#include <openthread/verhoeff_checksum.h>
#include "common/num_utils.hpp"
#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
#include <openthread/network_time.h>
@@ -8355,6 +8356,57 @@ void Interpreter::HandleIp6Receive(otMessage *aMessage, void *aContext)
}
#endif
#if OPENTHREAD_CONFIG_VERHOEFF_CHECKSUM_ENABLE
template <> otError Interpreter::Process<Cmd("verhoeff")>(Arg aArgs[])
{
otError error;
/**
* @cli verhoeff calculate
* @code
* verhoeff calculate 30731842
* 1
* Done
* @endcode
* @cparam verhoeff calculate @ca{decimalstring}
* @par api_copy
* #otVerhoeffChecksumCalculate
*/
if (aArgs[0] == "calculate")
{
char checksum;
VerifyOrExit(!aArgs[1].IsEmpty() && aArgs[2].IsEmpty(), error = OT_ERROR_INVALID_ARGS);
SuccessOrExit(error = otVerhoeffChecksumCalculate(aArgs[1].GetCString(), &checksum));
OutputLine("%c", checksum);
}
/**
* @cli verhoeff validate
* @code
* verhoeff validate 307318421
* Done
* @endcode
* @cparam verhoeff validate @ca{decimalstring}
* @par api_copy
* #otVerhoeffChecksumValidate
*/
else if (aArgs[0] == "validate")
{
VerifyOrExit(!aArgs[1].IsEmpty() && aArgs[2].IsEmpty(), error = OT_ERROR_INVALID_ARGS);
error = otVerhoeffChecksumValidate(aArgs[1].GetCString());
}
else
{
error = OT_ERROR_INVALID_COMMAND;
}
exit:
return error;
}
#endif // OPENTHREAD_CONFIG_VERHOEFF_CHECKSUM_ENABLE
#endif // OPENTHREAD_FTD || OPENTHREAD_MTD
void Interpreter::Initialize(otInstance *aInstance, otCliOutputCallback aCallback, void *aContext)
@@ -8653,6 +8705,9 @@ otError Interpreter::ProcessCommand(Arg aArgs[])
CmdEntry("uptime"),
#endif
CmdEntry("vendor"),
#if OPENTHREAD_CONFIG_VERHOEFF_CHECKSUM_ENABLE
CmdEntry("verhoeff"),
#endif
#endif // OPENTHREAD_FTD || OPENTHREAD_MTD
CmdEntry("version"),
};
+3
View File
@@ -360,6 +360,7 @@ openthread_core_files = [
"api/thread_ftd_api.cpp",
"api/trel_api.cpp",
"api/udp_api.cpp",
"api/verhoeff_checksum_api.cpp",
"backbone_router/backbone_tmf.cpp",
"backbone_router/backbone_tmf.hpp",
"backbone_router/bbr_leader.cpp",
@@ -736,6 +737,8 @@ openthread_core_files = [
"utils/slaac_address.hpp",
"utils/srp_client_buffers.cpp",
"utils/srp_client_buffers.hpp",
"utils/verhoeff_checksum.cpp",
"utils/verhoeff_checksum.hpp",
]
openthread_radio_sources = [
+2
View File
@@ -86,6 +86,7 @@ set(COMMON_SOURCES
api/thread_ftd_api.cpp
api/trel_api.cpp
api/udp_api.cpp
api/verhoeff_checksum_api.cpp
backbone_router/backbone_tmf.cpp
backbone_router/bbr_leader.cpp
backbone_router/bbr_local.cpp
@@ -257,6 +258,7 @@ set(COMMON_SOURCES
utils/power_calibration.cpp
utils/slaac_address.cpp
utils/srp_client_buffers.cpp
utils/verhoeff_checksum.cpp
)
set(RADIO_COMMON_SOURCES
+60
View File
@@ -0,0 +1,60 @@
/*
* Copyright (c) 2024, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* This file implements the Verhoeff Checksum public APIs.
*/
#include "openthread-core-config.h"
#if OPENTHREAD_CONFIG_VERHOEFF_CHECKSUM_ENABLE
#include <openthread/verhoeff_checksum.h>
#include "common/debug.hpp"
#include "utils/verhoeff_checksum.hpp"
using namespace ot::Utils;
otError otVerhoeffChecksumCalculate(const char *aDecimalString, char *aChecksum)
{
AssertPointerIsNotNull(aDecimalString);
AssertPointerIsNotNull(aChecksum);
return VerhoeffChecksum::Calculate(aDecimalString, *aChecksum);
}
otError otVerhoeffChecksumValidate(const char *aDecimalString)
{
AssertPointerIsNotNull(aDecimalString);
return VerhoeffChecksum::Validate(aDecimalString);
}
#endif // OPENTHREAD_CONFIG_VERHOEFF_CHECKSUM_ENABLE
+10
View File
@@ -141,6 +141,16 @@
#define OPENTHREAD_CONFIG_JAM_DETECTION_ENABLE 0
#endif
/**
* @def OPENTHREAD_CONFIG_VERHOEFF_CHECKSUM_ENABLE
*
* Define to 1 to enable Verhoeff checksum utility module.
*
*/
#ifndef OPENTHREAD_CONFIG_VERHOEFF_CHECKSUM_ENABLE
#define OPENTHREAD_CONFIG_VERHOEFF_CHECKSUM_ENABLE OPENTHREAD_CONFIG_BORDER_AGENT_EPHEMERAL_KEY_ENABLE
#endif
/**
* @def OPENTHREAD_CONFIG_MULTIPLE_INSTANCE_ENABLE
*
+149
View File
@@ -0,0 +1,149 @@
/*
* Copyright (c) 2024, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* This file implements Verhoeff checksum calculation and validation.
*/
#include "verhoeff_checksum.hpp"
#if OPENTHREAD_CONFIG_VERHOEFF_CHECKSUM_ENABLE
#include "common/code_utils.hpp"
#include "common/string.hpp"
namespace ot {
namespace Utils {
uint8_t VerhoeffChecksum::Lookup(uint8_t aIndex, const uint8_t aCompressedArray[])
{
// The values in the array are [0-9]. To save space, two
// entries are saved as a single byte in @p aCompressedArray,
// such that higher 4-bit corresponds to one entry, and the
// lower 4-bit to the next entry.
uint8_t result = aCompressedArray[aIndex / 2];
if ((aIndex & 1) == 0)
{
result >>= 4;
}
else
{
result &= 0x0f;
}
return result;
}
uint8_t VerhoeffChecksum::Multiply(uint8_t aFirst, uint8_t aSecond)
{
static uint8_t kMultiplication[][5] = {{0x01, 0x23, 0x45, 0x67, 0x89}, {0x12, 0x34, 0x06, 0x78, 0x95},
{0x23, 0x40, 0x17, 0x89, 0x56}, {0x34, 0x01, 0x28, 0x95, 0x67},
{0x40, 0x12, 0x39, 0x56, 0x78}, {0x59, 0x87, 0x60, 0x43, 0x21},
{0x65, 0x98, 0x71, 0x04, 0x32}, {0x76, 0x59, 0x82, 0x10, 0x43},
{0x87, 0x65, 0x93, 0x21, 0x04}, {0x98, 0x76, 0x54, 0x32, 0x10}};
return Lookup(aSecond, kMultiplication[aFirst]);
}
uint8_t VerhoeffChecksum::Permute(uint8_t aPosition, uint8_t aValue)
{
static uint8_t kPermutation[][5] = {{0x01, 0x23, 0x45, 0x67, 0x89}, {0x15, 0x76, 0x28, 0x30, 0x94},
{0x58, 0x03, 0x79, 0x61, 0x42}, {0x89, 0x16, 0x04, 0x35, 0x27},
{0x94, 0x53, 0x12, 0x68, 0x70}, {0x42, 0x86, 0x57, 0x39, 0x01},
{0x27, 0x93, 0x80, 0x64, 0x15}, {0x70, 0x46, 0x91, 0x32, 0x58}};
return Lookup(aValue, kPermutation[aPosition]);
}
uint8_t VerhoeffChecksum::InverseOf(uint8_t aValue)
{
static uint8_t kInverse[] = {0x04, 0x32, 0x15, 0x67, 0x89};
return Lookup(aValue, kInverse);
}
Error VerhoeffChecksum::Calculate(const char *aDecimalString, char &aChecksum)
{
Error error;
uint8_t code;
SuccessOrExit(error = ComputeCode(aDecimalString, code, /* aValidate */ false));
aChecksum = static_cast<char>('0' + InverseOf(code));
exit:
return error;
}
Error VerhoeffChecksum::Validate(const char *aDecimalString)
{
Error error;
uint8_t code;
SuccessOrExit(error = ComputeCode(aDecimalString, code, /* aValidate */ true));
VerifyOrExit(code == 0, error = kErrorFailed);
exit:
return error;
}
Error VerhoeffChecksum::ComputeCode(const char *aDecimalString, uint8_t &aCode, bool aValidate)
{
Error error = kErrorNone;
uint8_t code = 0;
uint16_t index = 0;
uint16_t length = StringLength(aDecimalString, kMaxStringLength + 1);
VerifyOrExit(length <= kMaxStringLength, error = kErrorInvalidArgs);
if (!aValidate)
{
length++;
index++;
}
for (; index < length; ++index)
{
char digit = aDecimalString[length - index - 1];
VerifyOrExit(digit >= '0' && digit <= '9', error = kErrorInvalidArgs);
code = Multiply(code, Permute(index % 8, static_cast<uint8_t>(digit - '0')));
}
aCode = code;
exit:
return error;
}
} // namespace Utils
} // namespace ot
#endif // OPENTHREAD_CONFIG_VERHOEFF_CHECKSUM_ENABLE
+99
View File
@@ -0,0 +1,99 @@
/*
* Copyright (c) 2024, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* This file includes definitions for Verhoeff checksum calculation and validation.
*/
#ifndef VERHOEFF_CHECKSUM_HPP_
#define VERHOEFF_CHECKSUM_HPP_
#include "openthread-core-config.h"
#if OPENTHREAD_CONFIG_VERHOEFF_CHECKSUM_ENABLE
#include <openthread/verhoeff_checksum.h>
#include "common/error.hpp"
namespace ot {
namespace Utils {
class VerhoeffChecksum
{
public:
/**
* Specifies the maximum length of decimal string input.
*
*/
static constexpr uint16_t kMaxStringLength = OT_VERHOEFF_CHECKSUM_MAX_STRING_LENGTH;
/**
* Calculates the Verhoeff checksum for a given decimal string.
*
*
* @param[in] a DecimalString The string containing decimal digits.
* @param[out] aChecksum Reference to a `char` to return the calculated checksum.
*
* @retval kErrorNone Successfully calculated the checksum, @p aChecksum is updated.
* @retval kErrorInvalidArgs The @p aDecimalString is not valid, i.e. it either contains chars other than
* ['0'-'9'], or is longer than `kMaxStringLength`.
*
*/
static Error Calculate(const char *aDecimalString, char &aChecksum);
/**
* Validates the Verhoeff checksum for a given decimal string.
*
* @param[in] aDecimalString The string containing decimal digits (last char is treated as checksum).
*
* @retval kErrorNone Successfully validated the checksum in @p aDecimalString.
* @retval kErrorFailed Checksum is not valid.
* @retval kErrorInvalidArgs The @p aDecimalString is not valid, i.e. it either contains chars other than
* ['0'-'9'], or is longer than `kMaxStringLength`.
*
*/
static Error Validate(const char *aDecimalString);
VerhoeffChecksum(void) = delete;
private:
static Error ComputeCode(const char *aDecimalString, uint8_t &aCode, bool aValidate);
static uint8_t Lookup(uint8_t aIndex, const uint8_t aCompressedArray[]);
static uint8_t Multiply(uint8_t aFirst, uint8_t aSecond);
static uint8_t Permute(uint8_t aPosition, uint8_t aValue);
static uint8_t InverseOf(uint8_t aValue);
};
} // namespace Utils
} // namespace ot
#endif // OPENTHREAD_CONFIG_VERHOEFF_CHECKSUM_ENABLE
#endif // VERHOEFF_CHECKSUM_HPP_
+62
View File
@@ -30,11 +30,13 @@
#include "common/message.hpp"
#include "common/numeric_limits.hpp"
#include "common/random.hpp"
#include "common/string.hpp"
#include "instance/instance.hpp"
#include "net/checksum.hpp"
#include "net/icmp6.hpp"
#include "net/ip4_types.hpp"
#include "net/udp6.hpp"
#include "utils/verhoeff_checksum.hpp"
#include "test_platform.h"
#include "test_util.hpp"
@@ -467,6 +469,62 @@ public:
}
};
#if OPENTHREAD_CONFIG_VERHOEFF_CHECKSUM_ENABLE
void TestVerhoeffChecksum(void)
{
static constexpr uint16_t kMaxStringSize = 50;
const char *kExamples[] = {"307318421", "487300178", "123455672", "0", "15",
"999999994", "000000001", "100000000", "2363"};
const char *kInvalidFormats[] = {
"307 318421",
"307318421 ",
" 307318421",
"ABCDE",
};
char string[kMaxStringSize];
char checksum;
char expectedChecksum;
printf("\nVerhoeffChecksum\n");
for (const char *example : kExamples)
{
uint16_t length = StringLength(example, kMaxStringSize - 1);
memcpy(string, example, length + 1);
printf("- \"%s\"\n", string);
SuccessOrQuit(Utils::VerhoeffChecksum::Validate(string));
expectedChecksum = string[length - 1];
string[length - 1] = (expectedChecksum == '0') ? '9' : (expectedChecksum - 1);
VerifyOrQuit(Utils::VerhoeffChecksum::Validate(string) == kErrorFailed);
string[length - 1] = '\0';
SuccessOrQuit(Utils::VerhoeffChecksum::Calculate(string, checksum));
VerifyOrQuit(checksum == expectedChecksum);
string[length - 1] = expectedChecksum == '0' ? '9' : (expectedChecksum - 1);
}
printf("\nInvalid format:\n");
for (const char *example : kInvalidFormats)
{
printf("- \"%s\"\n", example);
VerifyOrQuit(Utils::VerhoeffChecksum::Validate(example) == kErrorInvalidArgs);
VerifyOrQuit(Utils::VerhoeffChecksum::Calculate(example, checksum) == kErrorInvalidArgs);
}
}
#endif // OPENTHREAD_CONFIG_VERHOEFF_CHECKSUM_ENABLE
} // namespace ot
int main(void)
@@ -477,6 +535,10 @@ int main(void)
ot::TestTcp4MessageChecksum();
ot::TestUdp4MessageChecksum();
ot::TestIcmp4MessageChecksum();
#if OPENTHREAD_CONFIG_VERHOEFF_CHECKSUM_ENABLE
ot::TestVerhoeffChecksum();
#endif
printf("All tests passed\n");
return 0;
}