hex.hpp
Go to the documentation of this file.
1 //---------------------------------------------------------------------------//
2 // Copyright (c) 2018-2020 Mikhail Komarov <nemo@nil.foundation>
3 // Copyright (c) 2019 Aleksey Moskvin <zerg1996@yandex.ru>
4 //
5 // MIT License
6 //
7 // Permission is hereby granted, free of charge, to any person obtaining a copy
8 // of this software and associated documentation files (the "Software"), to deal
9 // in the Software without restriction, including without limitation the rights
10 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 // copies of the Software, and to permit persons to whom the Software is
12 // furnished to do so, subject to the following conditions:
13 //
14 // The above copyright notice and this permission notice shall be included in all
15 // copies or substantial portions of the Software.
16 //
17 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 // SOFTWARE.
24 //---------------------------------------------------------------------------//
25 
26 #ifndef CRYPTO3_CODEC_HEX_HPP
27 #define CRYPTO3_CODEC_HEX_HPP
28 
29 #include <iterator>
30 #include <stdexcept>
31 #include <type_traits>
32 
36 
38 
39 #include <boost/range/begin.hpp>
40 #include <boost/range/end.hpp>
41 
42 #include <boost/exception/exception.hpp>
43 #include <boost/exception/info.hpp>
44 #include <boost/throw_exception.hpp>
45 
46 namespace nil {
47  namespace crypto3 {
48  namespace codec {
49 
54  struct hex_decode_error : virtual boost::exception, virtual std::exception {};
55 
60  struct not_enough_input : virtual hex_decode_error {};
61 
67  struct non_hex_input : virtual hex_decode_error {};
68  typedef boost::error_info<struct bad_char_, char> bad_char;
69 
70  namespace detail {
76  template<typename Iterator>
78  typedef typename std::iterator_traits<Iterator>::value_type value_type;
79  };
80 
81  template<typename Container>
82  struct hex_iterator_traits<std::back_insert_iterator<Container>> {
83  typedef typename Container::value_type value_type;
84  };
85 
86  template<typename Container>
87  struct hex_iterator_traits<std::front_insert_iterator<Container>> {
88  typedef typename Container::value_type value_type;
89  };
90 
91  template<typename Container>
92  struct hex_iterator_traits<std::insert_iterator<Container>> {
93  typedef typename Container::value_type value_type;
94  };
95 
107  template<typename T, typename charType, typename traits>
108  struct hex_iterator_traits<std::ostream_iterator<T, charType, traits>> {
109  typedef T value_type;
110  };
111 
112  template<typename Iterator>
113  inline static bool iter_end(Iterator current, Iterator last) {
114  return current == last;
115  }
116 
117  template<typename T>
118  inline static bool ptr_end(const T *ptr, const T * /*end*/) {
119  return *ptr == '\0';
120  }
121  } // namespace detail
122 
128  template<typename Mode = mode::upper>
129  class hex {
130  typedef typename detail::hex_policy<Mode> policy_type;
131 
132  public:
134 
139 
142 
143  constexpr static const std::size_t encoded_value_bits = policy_type::encoded_value_bits;
145 
146  constexpr static const std::size_t decoded_value_bits = policy_type::decoded_value_bits;
148 
149  constexpr static const std::size_t encoded_block_values = policy_type::encoded_block_values;
150  constexpr static const std::size_t encoded_block_bits = policy_type::encoded_block_bits;
152 
153  constexpr static const std::size_t decoded_block_values = policy_type::decoded_block_values;
154  constexpr static const std::size_t decoded_block_bits = policy_type::decoded_block_bits;
156 
162  static encoded_block_type encode(const decoded_block_type &plaintext) {
163  BOOST_STATIC_ASSERT(std::tuple_size<decoded_block_type>::value == 1);
164 
165  encoded_block_type res = {0};
166 
167  typename encoded_block_type::iterator p = res.end();
168  typename decoded_block_type::value_type integral_plaintext = plaintext.back();
169 
170  for (std::size_t i = 0; i < encoded_block_bits / CHAR_BIT && p != res.begin();
171  ++i, integral_plaintext >>= 4) {
172  *--p = policy_type::constants()[integral_plaintext & 0x0F];
173  }
174 
175  return res;
176  }
177 
183  static decoded_block_type decode(const encoded_block_type &plaintext) {
184  BOOST_STATIC_ASSERT(std::tuple_size<decoded_block_type>::value == 1);
185 
186  decoded_block_type res = {0};
187 
188  for (const typename encoded_block_type::value_type &v : plaintext) {
189  res[0] = (16 * res[0]) + hex_char_to_int(v);
190  }
191 
192  return res;
193  }
194 
195  template<typename ProcessingMode>
197 
198  template<typename ProcessingMode, typename StateAccumulator, std::size_t ValueBits>
200  struct params_type {
202 
203  constexpr static const std::size_t value_bits = ValueBits;
204  constexpr static const std::size_t length_bits = CHAR_BIT * CHAR_BIT;
205  };
206 
208  };
209 
210  protected:
211  template<typename T>
212  static uint8_t hex_char_to_int(T val) {
213  char c = static_cast<char>(val);
214  uint8_t retval = 0;
215  if (c >= '0' && c <= '9') {
216  retval = static_cast<uint8_t>(c - '0');
217  } else if (c >= 'A' && c <= 'F') {
218  retval = static_cast<uint8_t>(c - 'A' + 10);
219  } else if (c >= 'a' && c <= 'f') {
220  retval = static_cast<uint8_t>(c - 'a' + 10);
221  } else {
222  BOOST_THROW_EXCEPTION(non_hex_input() << bad_char(c));
223  }
224  return static_cast<char>(retval);
225  }
226  };
227  } // namespace codec
228  } // namespace crypto3
229 } // namespace nil
230 
231 #endif
Hex codec. Meets the requirements of Codec.
Definition: hex.hpp:129
constexpr static const std::size_t encoded_value_bits
Definition: hex.hpp:143
detail::isomorphic_encoding_mode< hex< Mode > > stream_encoder_type
Definition: hex.hpp:140
policy_type::mode_type mode_type
Definition: hex.hpp:133
static encoded_block_type encode(const decoded_block_type &plaintext)
Encodes single atomic data block.
Definition: hex.hpp:162
nop_preprocessor decoding_preprocessor_type
Definition: hex.hpp:138
policy_type::encoded_value_type encoded_value_type
Definition: hex.hpp:144
constexpr static const std::size_t decoded_block_values
Definition: hex.hpp:153
constexpr static const std::size_t encoded_block_bits
Definition: hex.hpp:150
detail::isomorphic_decoding_mode< hex< Mode > > stream_decoder_type
Definition: hex.hpp:141
nop_finalizer encoding_finalizer_type
Definition: hex.hpp:135
constexpr static const std::size_t decoded_value_bits
Definition: hex.hpp:146
policy_type::encoded_block_type encoded_block_type
Definition: hex.hpp:151
constexpr static const std::size_t encoded_block_values
Definition: hex.hpp:149
static decoded_block_type decode(const encoded_block_type &plaintext)
Decodes single atomic data block.
Definition: hex.hpp:183
static uint8_t hex_char_to_int(T val)
Definition: hex.hpp:212
constexpr static const std::size_t decoded_block_bits
Definition: hex.hpp:154
nop_preprocessor encoding_preprocessor_type
Definition: hex.hpp:137
nop_finalizer decoding_finalizer_type
Definition: hex.hpp:136
policy_type::decoded_value_type decoded_value_type
Definition: hex.hpp:147
policy_type::decoded_block_type decoded_block_type
Definition: hex.hpp:155
boost::mpl::apply< AccumulatorSet, tag::codec< Mode > >::type::result_type codec(const AccumulatorSet &acc)
Definition: accumulators/codec.hpp:261
boost::error_info< struct bad_char_, char > bad_char
Definition: base_policy.hpp:74
Definition: pair.hpp:31
Own detail::hex_iterator_traits class allows to get inside of some kinds of output iterator and get t...
Definition: hex.hpp:77
std::iterator_traits< Iterator >::value_type value_type
Definition: hex.hpp:78
Definition: hex_policy.hpp:51
constexpr static const std::size_t decoded_block_bits
Definition: hex_policy.hpp:65
constexpr static const std::uint8_t encoded_block_bits
Definition: hex_policy.hpp:69
std::array< decoded_value_type, decoded_block_values > decoded_block_type
Definition: hex_policy.hpp:66
constexpr static const std::size_t encoded_value_bits
Definition: hex_policy.hpp:61
constexpr static const std::size_t decoded_block_values
Definition: hex_policy.hpp:64
std::array< encoded_value_type, encoded_block_values > encoded_block_type
Definition: hex_policy.hpp:70
byte_type encoded_value_type
Definition: hex_policy.hpp:62
byte_type decoded_value_type
Definition: hex_policy.hpp:59
Mode mode_type
Definition: hex_policy.hpp:52
constexpr static const std::size_t decoded_value_bits
Definition: hex_policy.hpp:58
constexpr static const std::size_t encoded_block_values
Definition: hex_policy.hpp:68
Definition: fixed_block_stream_processor.hpp:46
constexpr static const std::size_t value_bits
Definition: hex.hpp:203
constexpr static const std::size_t length_bits
Definition: hex.hpp:204
stream_endian::little_octet_big_bit endian_type
Definition: hex.hpp:201
fixed_block_stream_processor< ProcessingMode, StateAccumulator, params_type > type
Definition: hex.hpp:207
Base exception class for all hex decoding errors.
Definition: hex.hpp:54
Thrown when a non-hex value (0-9, A-F) encountered when decoding. Contains the offending character.
Definition: hex.hpp:67
Definition: codec_state.hpp:37
Definition: codec_state.hpp:46
Thrown when the input sequence unexpectedly ends.
Definition: hex.hpp:60
Definition: algebra/include/nil/crypto3/detail/stream_endian.hpp:45