10#include <botan/exceptn.h>
11#include <botan/mem_ops.h>
12#include <botan/internal/charset.h>
13#include <botan/internal/ct_utils.h>
14#include <botan/internal/fmt.h>
15#include <botan/internal/int_utils.h>
16#include <botan/internal/loadstor.h>
22uint16_t hex_encode_2nibble(uint8_t n8,
bool uppercase) {
24 const uint16_t a_mask = uppercase ? 0x0707 : 0x2727;
26 const uint16_t n = (
static_cast<uint16_t
>(n8 & 0xF0) << 4) | (n8 & 0x0F);
30 return n + 0x3030 + diff;
35void hex_encode(
char output[],
const uint8_t input[],
size_t input_length,
bool uppercase) {
36 for(
size_t i = 0; i != input_length; ++i) {
37 const uint16_t h = hex_encode_2nibble(input[i], uppercase);
43std::string
hex_encode(
const uint8_t input[],
size_t input_length,
bool uppercase) {
44 std::string output(2 * input_length, 0);
47 hex_encode(&output.front(), input, input_length, uppercase);
55uint8_t hex_char_to_bin(
char input) {
57 constexpr uint64_t v_lo =
make_uint64(0,
'0',
'a',
'A',
' ',
'\n',
'\t',
'\r');
58 constexpr uint64_t v_range =
make_uint64(0, 10, 6, 6, 1, 1, 1, 1);
60 const uint8_t x =
static_cast<uint8_t
>(input);
61 const uint64_t x8 = x * 0x0101010101010101;
66 const uint64_t val_v = 0xd0a9c960767773 ^
static_cast<uint64_t
>(0xFF - x) << 56;
73size_t hex_decode(uint8_t output[],
const char input[],
size_t input_length,
size_t& input_consumed,
bool ignore_ws) {
75 bool top_nibble =
true;
79 for(
size_t i = 0; i != input_length; ++i) {
80 const uint8_t bin = hex_char_to_bin(input[i]);
83 if(bin == 0x80 && ignore_ws) {
96 top_nibble = !top_nibble;
102 input_consumed = input_length;
103 size_t written = (
out_ptr - output);
117size_t hex_decode(uint8_t output[],
const char input[],
size_t input_length,
bool ignore_ws) {
119 size_t written =
hex_decode(output, input, input_length, consumed, ignore_ws);
121 if(consumed != input_length) {
128size_t hex_decode(uint8_t output[], std::string_view input,
bool ignore_ws) {
129 return hex_decode(output, input.data(), input.length(), ignore_ws);
132size_t hex_decode(std::span<uint8_t> output, std::string_view input,
bool ignore_ws) {
133 return hex_decode(output.data(), input.data(), input.length(), ignore_ws);
139 size_t written =
hex_decode(bin.data(), input, input_length, ignore_ws);
149std::vector<uint8_t>
hex_decode(
const char input[],
size_t input_length,
bool ignore_ws) {
150 std::vector<uint8_t> bin(1 + input_length / 2);
152 size_t written =
hex_decode(bin.data(), input, input_length, ignore_ws);
158std::vector<uint8_t>
hex_decode(std::string_view input,
bool ignore_ws) {
159 return hex_decode(input.data(), input.size(), ignore_ws);
constexpr uint8_t get_byte(T input)
std::string format_char_for_display(char c)
constexpr T swar_lt(T a, T b)
constexpr auto out_ptr(T &outptr) noexcept
constexpr uint64_t make_uint64(uint8_t i0, uint8_t i1, uint8_t i2, uint8_t i3, uint8_t i4, uint8_t i5, uint8_t i6, uint8_t i7)
std::string fmt(std::string_view format, const T &... args)
constexpr T swar_in_range(T v, T lower, T upper)
secure_vector< uint8_t > hex_decode_locked(const char input[], size_t input_length, bool ignore_ws)
constexpr size_t index_of_first_set_byte(T v)
void hex_encode(char output[], const uint8_t input[], size_t input_length, bool uppercase)
size_t hex_decode(uint8_t output[], const char input[], size_t input_length, size_t &input_consumed, bool ignore_ws)
std::vector< T, secure_allocator< T > > secure_vector
constexpr void clear_mem(T *ptr, size_t n)