Bitcoin ABC  0.22.13
P2P Digital Currency
asmap.cpp
Go to the documentation of this file.
1 // Copyright (c) 2019 The Bitcoin Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 
5 #include <crypto/common.h>
6 
7 #include <cassert>
8 #include <vector>
9 
10 namespace {
11 
12 uint32_t DecodeBits(std::vector<bool>::const_iterator &bitpos,
13  const std::vector<bool>::const_iterator &endpos,
14  uint8_t minval, const std::vector<uint8_t> &bit_sizes) {
15  uint32_t val = minval;
16  bool bit;
17  for (std::vector<uint8_t>::const_iterator bit_sizes_it = bit_sizes.begin();
18  bit_sizes_it != bit_sizes.end(); ++bit_sizes_it) {
19  if (bit_sizes_it + 1 != bit_sizes.end()) {
20  if (bitpos == endpos) {
21  break;
22  }
23  bit = *bitpos;
24  bitpos++;
25  } else {
26  bit = 0;
27  }
28  if (bit) {
29  val += (1 << *bit_sizes_it);
30  } else {
31  for (int b = 0; b < *bit_sizes_it; b++) {
32  if (bitpos == endpos) {
33  break;
34  }
35  bit = *bitpos;
36  bitpos++;
37  val += bit << (*bit_sizes_it - 1 - b);
38  }
39  return val;
40  }
41  }
42  return -1;
43 }
44 
45 const std::vector<uint8_t> TYPE_BIT_SIZES{0, 0, 1};
46 uint32_t DecodeType(std::vector<bool>::const_iterator &bitpos,
47  const std::vector<bool>::const_iterator &endpos) {
48  return DecodeBits(bitpos, endpos, 0, TYPE_BIT_SIZES);
49 }
50 
51 const std::vector<uint8_t> ASN_BIT_SIZES{15, 16, 17, 18, 19,
52  20, 21, 22, 23, 24};
53 uint32_t DecodeASN(std::vector<bool>::const_iterator &bitpos,
54  const std::vector<bool>::const_iterator &endpos) {
55  return DecodeBits(bitpos, endpos, 1, ASN_BIT_SIZES);
56 }
57 
58 const std::vector<uint8_t> MATCH_BIT_SIZES{1, 2, 3, 4, 5, 6, 7, 8};
59 uint32_t DecodeMatch(std::vector<bool>::const_iterator &bitpos,
60  const std::vector<bool>::const_iterator &endpos) {
61  return DecodeBits(bitpos, endpos, 2, MATCH_BIT_SIZES);
62 }
63 
64 const std::vector<uint8_t> JUMP_BIT_SIZES{5, 6, 7, 8, 9, 10, 11, 12, 13,
65  14, 15, 16, 17, 18, 19, 20, 21, 22,
66  23, 24, 25, 26, 27, 28, 29, 30};
67 uint32_t DecodeJump(std::vector<bool>::const_iterator &bitpos,
68  const std::vector<bool>::const_iterator &endpos) {
69  return DecodeBits(bitpos, endpos, 17, JUMP_BIT_SIZES);
70 }
71 
72 } // namespace
73 
74 uint32_t Interpret(const std::vector<bool> &asmap,
75  const std::vector<bool> &ip) {
76  std::vector<bool>::const_iterator pos = asmap.begin();
77  const std::vector<bool>::const_iterator endpos = asmap.end();
78  uint8_t bits = ip.size();
79  uint32_t default_asn = 0;
80  uint32_t opcode, jump, match, matchlen;
81  while (pos != endpos) {
82  opcode = DecodeType(pos, endpos);
83  if (opcode == 0) {
84  return DecodeASN(pos, endpos);
85  } else if (opcode == 1) {
86  jump = DecodeJump(pos, endpos);
87  if (bits == 0) {
88  break;
89  }
90  if (ip[ip.size() - bits]) {
91  if (jump >= endpos - pos) {
92  break;
93  }
94  pos += jump;
95  }
96  bits--;
97  } else if (opcode == 2) {
98  match = DecodeMatch(pos, endpos);
99  matchlen = CountBits(match) - 1;
100  for (uint32_t bit = 0; bit < matchlen; bit++) {
101  if (bits == 0) {
102  break;
103  }
104  if ((ip[ip.size() - bits]) !=
105  ((match >> (matchlen - 1 - bit)) & 1)) {
106  return default_asn;
107  }
108  bits--;
109  }
110  } else if (opcode == 3) {
111  default_asn = DecodeASN(pos, endpos);
112  } else {
113  break;
114  }
115  }
116  // 0 is not a valid ASN
117  return 0;
118 }
uint32_t Interpret(const std::vector< bool > &asmap, const std::vector< bool > &ip)
Definition: asmap.cpp:74
static uint64_t CountBits(uint64_t x)
Return the smallest number n such that (x >> n) == 0 (or 64 if the highest bit in x is set...
Definition: common.h:76