Bitcoin Core  0.19.99
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 <vector>
6 #include <assert.h>
7 #include <crypto/common.h>
8 
9 namespace {
10 
11 uint32_t DecodeBits(std::vector<bool>::const_iterator& bitpos, const std::vector<bool>::const_iterator& endpos, uint8_t minval, const std::vector<uint8_t> &bit_sizes)
12 {
13  uint32_t val = minval;
14  bool bit;
15  for (std::vector<uint8_t>::const_iterator bit_sizes_it = bit_sizes.begin();
16  bit_sizes_it != bit_sizes.end(); ++bit_sizes_it) {
17  if (bit_sizes_it + 1 != bit_sizes.end()) {
18  if (bitpos == endpos) break;
19  bit = *bitpos;
20  bitpos++;
21  } else {
22  bit = 0;
23  }
24  if (bit) {
25  val += (1 << *bit_sizes_it);
26  } else {
27  for (int b = 0; b < *bit_sizes_it; b++) {
28  if (bitpos == endpos) break;
29  bit = *bitpos;
30  bitpos++;
31  val += bit << (*bit_sizes_it - 1 - b);
32  }
33  return val;
34  }
35  }
36  return -1;
37 }
38 
39 const std::vector<uint8_t> TYPE_BIT_SIZES{0, 0, 1};
40 uint32_t DecodeType(std::vector<bool>::const_iterator& bitpos, const std::vector<bool>::const_iterator& endpos)
41 {
42  return DecodeBits(bitpos, endpos, 0, TYPE_BIT_SIZES);
43 }
44 
45 const std::vector<uint8_t> ASN_BIT_SIZES{15, 16, 17, 18, 19, 20, 21, 22, 23, 24};
46 uint32_t DecodeASN(std::vector<bool>::const_iterator& bitpos, const std::vector<bool>::const_iterator& endpos)
47 {
48  return DecodeBits(bitpos, endpos, 1, ASN_BIT_SIZES);
49 }
50 
51 
52 const std::vector<uint8_t> MATCH_BIT_SIZES{1, 2, 3, 4, 5, 6, 7, 8};
53 uint32_t DecodeMatch(std::vector<bool>::const_iterator& bitpos, const std::vector<bool>::const_iterator& endpos)
54 {
55  return DecodeBits(bitpos, endpos, 2, MATCH_BIT_SIZES);
56 }
57 
58 
59 const std::vector<uint8_t> JUMP_BIT_SIZES{5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30};
60 uint32_t DecodeJump(std::vector<bool>::const_iterator& bitpos, const std::vector<bool>::const_iterator& endpos)
61 {
62  return DecodeBits(bitpos, endpos, 17, JUMP_BIT_SIZES);
63 }
64 
65 }
66 
67 uint32_t Interpret(const std::vector<bool> &asmap, const std::vector<bool> &ip)
68 {
69  std::vector<bool>::const_iterator pos = asmap.begin();
70  const std::vector<bool>::const_iterator endpos = asmap.end();
71  uint8_t bits = ip.size();
72  uint32_t default_asn = 0;
73  uint32_t opcode, jump, match, matchlen;
74  while (pos != endpos) {
75  opcode = DecodeType(pos, endpos);
76  if (opcode == 0) {
77  return DecodeASN(pos, endpos);
78  } else if (opcode == 1) {
79  jump = DecodeJump(pos, endpos);
80  if (bits == 0) break;
81  if (ip[ip.size() - bits]) {
82  if (jump >= endpos - pos) break;
83  pos += jump;
84  }
85  bits--;
86  } else if (opcode == 2) {
87  match = DecodeMatch(pos, endpos);
88  matchlen = CountBits(match) - 1;
89  for (uint32_t bit = 0; bit < matchlen; bit++) {
90  if (bits == 0) break;
91  if ((ip[ip.size() - bits]) != ((match >> (matchlen - 1 - bit)) & 1)) {
92  return default_asn;
93  }
94  bits--;
95  }
96  } else if (opcode == 3) {
97  default_asn = DecodeASN(pos, endpos);
98  } else {
99  break;
100  }
101  }
102  return 0; // 0 is not a valid ASN
103 }
uint32_t Interpret(const std::vector< bool > &asmap, const std::vector< bool > &ip)
Definition: asmap.cpp:67
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:83