10#include <botan/exceptn.h>
11#include <botan/mem_ops.h>
12#include <botan/internal/charset.h>
13#include <botan/internal/fmt.h>
14#include <botan/internal/int_utils.h>
15#include <botan/internal/loadstor.h>
21uint16_t hex_encode_2nibble(uint8_t n8,
bool uppercase) {
23 const uint16_t a_mask = uppercase ? 0x0707 : 0x2727;
25 const uint16_t n = (
static_cast<uint16_t
>(n8 & 0xF0) << 4) | (n8 & 0x0F);
29 return n + 0x3030 + diff;
34void hex_encode(
char output[],
const uint8_t input[],
size_t input_length,
bool uppercase) {
35 for(
size_t i = 0; i != input_length; ++i) {
36 const uint16_t h = hex_encode_2nibble(input[i], uppercase);
42std::string
hex_encode(
const uint8_t input[],
size_t input_length,
bool uppercase) {
43 std::string output(2 * input_length, 0);
45 if(input_length > 0) {
46 hex_encode(&output.front(), input, input_length, uppercase);
54uint8_t hex_char_to_bin(
char input) {
56 constexpr uint64_t v_lo =
make_uint64(0,
'0',
'a',
'A',
' ',
'\n',
'\t',
'\r');
57 constexpr uint64_t v_range =
make_uint64(0, 10, 6, 6, 1, 1, 1, 1);
59 const uint8_t x =
static_cast<uint8_t
>(input);
60 const uint64_t x8 = x * 0x0101010101010101;
65 const uint64_t val_v = 0xd0a9c960767773 ^
static_cast<uint64_t
>(0xFF - x) << 56;
72size_t hex_decode(uint8_t output[],
const char input[],
size_t input_length,
size_t& input_consumed,
bool ignore_ws) {
74 bool top_nibble =
true;
78 for(
size_t i = 0; i != input_length; ++i) {
79 const uint8_t bin = hex_char_to_bin(input[i]);
82 if(bin == 0x80 && ignore_ws) {
95 top_nibble = !top_nibble;
101 input_consumed = input_length;
102 size_t written = (
out_ptr - output);
116size_t hex_decode(uint8_t output[],
const char input[],
size_t input_length,
bool ignore_ws) {
118 size_t written =
hex_decode(output, input, input_length, consumed, ignore_ws);
120 if(consumed != input_length) {
127size_t hex_decode(uint8_t output[], std::string_view input,
bool ignore_ws) {
128 return hex_decode(output, input.data(), input.length(), ignore_ws);
131size_t hex_decode(std::span<uint8_t> output, std::string_view input,
bool ignore_ws) {
132 return hex_decode(output.data(), input.data(), input.length(), ignore_ws);
138 size_t written =
hex_decode(bin.data(), input, input_length, ignore_ws);
148std::vector<uint8_t>
hex_decode(
const char input[],
size_t input_length,
bool ignore_ws) {
149 std::vector<uint8_t> bin(1 + input_length / 2);
151 size_t written =
hex_decode(bin.data(), input, input_length, ignore_ws);
157std::vector<uint8_t>
hex_decode(std::string_view input,
bool ignore_ws) {
158 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)