/*
*******************************************************************************
\file dec.h
\brief Decimal strings
\project bee2 [cryptographic library]
\created 2015.11.09
\version 2025.04.15
\copyright The Bee2 authors
\license Licensed under the Apache License, Version 2.0 (see LICENSE.txt).
*******************************************************************************
*/

/*!
*******************************************************************************
\file dec.h
\brief Десятичные строки
*******************************************************************************
*/

#ifndef __BEE2_DEC_H
#define __BEE2_DEC_H

#include "bee2/defs.h"

#ifdef __cplusplus
extern "C" {
#endif

/*!
*******************************************************************************
\file dec.h

Реализовано управление десятичными строками -- словами в алфавите {'0',..,'9'}, 
которые представляют числа и буферы памяти. 

Первый символ (цифра) является старшим, т.е. используется порядок big-endian. 
Порядок можно изменить с помощью функции strRev().

Реализованы алгоритмы Луна (1954) и Дамма (2004) расчета контрольных цифр 
десятичной строки. Алгоритм Луна стандартизирован в ISO/IEC 7812.

Характеристики алгоритма Луна (https://en.wikipedia.org/wiki/Luhn_algorithm):
-	обнаруживает одиночные ошибки в цифрах;
-	обнаруживает все одиночные перстановки соседних цифр, кроме 09 <-> 90;
-	обнаруживает все одиночные ошибки в повторных цифрах, кроме 22 <-> 55, 
	33 <-> 66 и 44 <-> 77.

Алгоритма Дамма (https://en.wikipedia.org/wiki/Damm_algorithm) обнаруживает
все одиночные ошибки и перестановки.

Длина строки, контрольная цифра которой проверяется, на 1 больше длины строки,
контрольная цифра которой вычисляется. Считается, что контрольная цифра 
проверяемой строки добавлена справа. Именно так добавляется 
контрольная цифра Луна к номеру кредитной карты (как правило, 15-значному) 
и к номеру IMEI (как правило, 14-значному).

\pre Во все функции кроме decIsValid() передаются корректные десятичные строки 
и буферы памяти.
*******************************************************************************
*/

/*!	\brief Корректная десятичная строка?

	Проверяется корректность десятичной строки dec. Строка считается
	корректной, если она состоит из символов алфавита {'0',...,'9'}.
	\return Признак корректности.
	\safe Функция нерегулярна.
*/
bool_t decIsValid(
	const char* dec		/*!< [in] десятичная строка */
);

/*!	\brief Число старших нулевых цифр

	Определяется длина серии из нулевых старших цифр в строке dec.
	\return Длина серии.
	\remark CLZ == Count of Leading Zeros
	\safe Функция нерегулярна.
*/
size_t decCLZ(
	const char* dec		/*!< [in] десятичная строка */
);

/*!	\brief Загрузка из числа u32

	Младшие count десятичных цифр числа num преобразуются в десятичную строку
	[count + 1]dec.
*/
void decFromU32(
	char* dec,			/*!< [out] десятичная строка */
	size_t count,		/*!< [in] число цифр */
	register u32 num	/*!< [in] число */
);

/*!	\brief Преобразование в число u32

	Десятичная строка dec преобразуется в число u32.
	\return Искомое число \mod 2^32.
	\warning Возможно переполнение. Проверка отсутствия переполнения:
		strLen(dec) - decCLZ(dec) < 10 ||
			strLen(dec) - decCLZ(dec) == 10 && 
				strCmp(dec + decCLZ(dec), "4294967295") <= 0.
*/
u32 decToU32(
	const char* dec		/*!< [in] десятичная строка */
);

#ifdef U64_SUPPORT

/*!	\brief Загрузка из числа u64

	Младшие count десятичных цифр числа num преобразуются в десятичную строку
	[count + 1]dec.
*/
void decFromU64(
	char* dec,			/*!< [out] десятичная строка */
	size_t count,		/*!< [in] число цифр */
	register u64 num	/*!< [in] число */
);

/*!	\brief Преобразование в число u64

	Десятичная строка dec преобразуется в число u64.
	\return Искомое число \mod 2^64.
	\warning Возможно переполнение. Проверка отсутствия переполнения:
		strLen(dec) - decCLZ() < 20 ||
			strLen(dec) - decCLZ() == 20 && 
				strCmp(dec + decCLZ(), "18446744073709551615") <= 0.
*/
u64 decToU64(
	const char* dec		/*!< [in] десятичная строка */
);

#endif // U64_SUPPORT

/*!	\brief Вычисление контрольной цифры Луна

	С помошью алгоритма Луна определяется контрольная цифра 
	десятичной строки dec.
	\return Контрольная цифра.
*/
char decLuhnCalc(
	const char* dec		/*!< [in] десятичная строка */
);

/*!	\brief Проверка контрольной цифры Луна

	С помошью алгоритма Луна проверяется контрольная цифра, записанная в
	конце десятичной строки dec.
	\return Признак успеха.
*/
bool_t decLuhnVerify(
	const char* dec		/*!< [in] десятичная строка */
);

/*!	\brief Вычисление контрольной цифры Дамма

	С помошью алгоритма Дамма определяется контрольная цифра 
	десятичной строки dec.
	\return Контрольная цифра.
*/
char decDammCalc(
	const char* dec		/*!< [in] десятичная строка */
);

/*!	\brief Проверка контрольной цифры Дамма

	С помошью алгоритма Дамма проверяется контрольная цифра, записанная в
	конце десятичной строки dec.
	\return Признак успеха.
*/
bool_t decDammVerify(
	const char* dec		/*!< [in] десятичная строка */
);

#ifdef __cplusplus
} /* extern "C" */
#endif

#endif /* __BEE2_DEC_H */
