Euphoria
drunken_bishop.cc
Go to the documentation of this file.
1 #include "core/drunken_bishop.h"
2 
3 #include "assert/assert.h"
4 
5 #include <algorithm>
6 
7 
8 namespace eu::core
9 {
10  // drunken bishop algorithm inspired by
11  // https://blog.benjojo.co.uk/post/ssh-randomart-how-does-it-work-art
12  // todo(Gustav): possible incorperate http://www.ece.cmu.edu/~adrian/projects/validation/validation.pdf
13 
14 
15  template<typename T, int total_bytes>
16  std::vector<U8>
18  {
19  auto bytes = std::vector<U8>{};
20  for(int byte_index=0; byte_index<total_bytes; byte_index +=1)
21  {
22  const U8 byte = static_cast<U8>
23  (
24  0xFF & (hash >> (((total_bytes-1)-byte_index) * 8))
25  );
26  bytes.emplace_back(byte);
27  }
28  return bytes;
29  }
30 
31 
32  std::vector<U8>
33  to_bytes(U32 hash)
34  {
35  return to_bytes_generic<U32, 4>(hash);
36  }
37 
38 
39  std::vector<U8>
40  to_bytes(U64 hash)
41  {
42  return to_bytes_generic<U64, 8>(hash);
43  }
44 
45 
46  std::vector<int>
47  to_codes(U8 byte, bool msb_first)
48  {
49  auto codes = std::vector<int>{};
50  for(int step=0; step<8; step += 2)
51  {
52  const auto code_entry = msb_first
53  ? (byte >> (6-step)) & 3
54  : (byte >> step) & 3
55  ;
56  codes.emplace_back(code_entry);
57  }
58  return codes;
59  }
60 
61 
62  std::vector<int>
63  to_codes(const std::vector<U8>& bytes, bool msb_first)
64  {
65  auto codes = std::vector<int>{};
66  for(auto byte: bytes)
67  {
68  const auto cc = to_codes(byte, msb_first);
69  for(auto c: cc)
70  {
71  codes.emplace_back(c);
72  }
73  }
74  return codes;
75  }
76 
77 
78  Table<int>
80  (
81  U32 hash,
82  int width,
83  int height,
84  bool msb_first,
85  int startx,
86  int starty
87  )
88  {
90  (
91  to_codes(to_bytes(hash), msb_first),
92  width,
93  height,
94  startx,
95  starty
96  );
97  }
98 
99  Table<int>
101  (
102  U64 hash,
103  int width,
104  int height,
105  bool msb_first,
106  int startx,
107  int starty
108  )
109  {
111  (
112  to_codes(to_bytes(hash), msb_first),
113  width,
114  height,
115  startx,
116  starty
117  );
118  }
119 
120  Table<int>
122  (
123  const std::vector<int>& codes,
124  int width,
125  int height,
126  int startx,
127  int starty
128  )
129  {
130  auto table = core::Table<int>::from_width_height(width, height, 0);
131  auto x = startx != -1? startx : width/2;
132  auto y = starty != -1? starty : height/2;
133 
134  for(auto code: codes)
135  {
136  constexpr int vertical_mask = 0b10;
137  constexpr int horizontal_mask = 0b01;
138 
139  const auto dy = (vertical_mask & code) != 0 ? 1 : -1;
140  const auto dx = (horizontal_mask & code) != 0 ? 1 : -1;
141 
142  x = keep_within(table.get_indices().get_range_x(), x + dx);
143  y = keep_within(table.get_indices().get_range_y(), y + dy);
144 
145  table[{x, y}] += 1;
146  }
147 
148  return table;
149  }
150 
151 
152  std::vector<std::string>
154  {
155  return
156  {
157  " ", ".", "o", "+", "=",
158  "*", "B", "O", "X", "@",
159  "%", "&", "#", "/", "?"
160  };
161  }
162 
163 
164  std::vector<std::string>
166  (
167  const Table<int>& table,
168  const std::vector<std::string>& characters
169  )
170  {
171  auto rr = std::vector<std::string>{};
172 
173  for(int y=0; y<table.get_height(); y+=1)
174  {
175  std::string r;
176  for(int x=0; x<table.get_width(); x+=1)
177  {
178  const auto v = std::max
179  (
180  0,
181  std::min
182  (
183  table[{x,y}],
184  c_sizet_to_int(characters.size())
185  )
186  );
187  r += characters[v];
188  }
189  rr.emplace_back(r);
190  }
191 
192  return rr;
193  }
194 
195  // todo(Gustav): add image collapse with palette
196 }
197 
std::vector< U8 > to_bytes_generic(T hash)
std::vector< std::string > render_table(const Table< int > &table, const std::vector< std::string > &characters)
Table< int > get_drunken_bishop_result(U32 hash, int width, int height, bool msb_first, int startx, int starty)
std::vector< int > to_codes(U8 byte, bool msb_first)
std::vector< U8 > to_bytes(U32 hash)
std::vector< std::string > get_ssh_characters()
T keep_within(const Range< T > &range, T value)
Definition: range.h:115
int c_sizet_to_int(size_t t)
Definition: cint.cc:11
std::uint32_t U32
Definition: ints.h:13
std::uint8_t U8
Definition: ints.h:15
size2f min(const size2f lhs, const size2f rhs)
Definition: size2.cc:140
std::uint64_t U64
Definition: ints.h:12
size2f max(const size2f lhs, const size2f rhs)
Definition: size2.cc:149
Idx get_height() const
Definition: table.h:158
Idx get_width() const
Definition: table.h:153
static Table from_width_height(Idx width, Idx height, T d=T())
Definition: table.h:23