PageRenderTime 46ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

/phpBB/includes/captcha/captcha_gd_wave.php

https://github.com/Jipem/phpbb
PHP | 843 lines | 730 code | 48 blank | 65 comment | 16 complexity | 5b01aa7952b6b049249d4e4dcbc918ae MD5 | raw file
Possible License(s): AGPL-1.0
  1. <?php
  2. /**
  3. *
  4. * This file is part of the phpBB Forum Software package.
  5. *
  6. * @copyright (c) phpBB Limited <https://www.phpbb.com>
  7. * @license GNU General Public License, version 2 (GPL-2.0)
  8. *
  9. * For full copyright and license information, please see
  10. * the docs/CREDITS.txt file.
  11. *
  12. */
  13. /**
  14. * Wave3D CAPTCHA
  15. */
  16. class captcha
  17. {
  18. var $width = 360;
  19. var $height = 96;
  20. function execute($code, $seed)
  21. {
  22. global $starttime;
  23. // seed the random generator
  24. mt_srand($seed);
  25. // set height and width
  26. $img_x = $this->width;
  27. $img_y = $this->height;
  28. // Generate image
  29. $img = imagecreatetruecolor($img_x, $img_y);
  30. $x_grid = mt_rand(6, 10);
  31. $y_grid = mt_rand(6, 10);
  32. // Ok, so lets cut to the chase. We could accurately represent this in 3d and
  33. // do all the appropriate linear transforms. my questions is... why bother?
  34. // The computational overhead is unnecessary when you consider the simple fact:
  35. // we're not here to accurately represent a model, but to just show off some random-ish
  36. // polygons
  37. // Conceive of 3 spaces.
  38. // 1) planar-space (discrete "pixel" grid)
  39. // 2) 3-space. (planar-space with z/height aspect)
  40. // 3) image space (pixels on the screen)
  41. // resolution of the planar-space we're embedding the text code in
  42. $plane_x = 100;
  43. $plane_y = 30;
  44. $subdivision_factor = 3;
  45. // $box is the 4 points in img_space that correspond to the corners of the plane in 3-space
  46. $box = array(
  47. 'upper_left' => array(
  48. 'x' => mt_rand(5, 15),
  49. 'y' => mt_rand(10, 15)
  50. ),
  51. 'upper_right' => array(
  52. 'x' => mt_rand($img_x - 35, $img_x - 19),
  53. 'y' => mt_rand(10, 17)
  54. ),
  55. 'lower_left' => array(
  56. 'x' => mt_rand($img_x - 45, $img_x - 5),
  57. 'y' => mt_rand($img_y - 15, $img_y - 0),
  58. ),
  59. );
  60. $box['lower_right'] = array(
  61. 'x' => $box['lower_left']['x'] + $box['upper_left']['x'] - $box['upper_right']['x'],
  62. 'y' => $box['lower_left']['y'] + $box['upper_left']['y'] - $box['upper_right']['y'],
  63. );
  64. // TODO
  65. $background = imagecolorallocate($img, mt_rand(155, 255), mt_rand(155, 255), mt_rand(155, 255));
  66. imagefill($img, 0, 0, $background);
  67. $black = imagecolorallocate($img, 0, 0, 0);
  68. $random = array();
  69. $fontcolors = array();
  70. for ($i = 0; $i < 15; ++$i)
  71. {
  72. $random[$i] = imagecolorallocate($img, mt_rand(120, 255), mt_rand(120, 255), mt_rand(120, 255));
  73. }
  74. $fontcolors[0] = imagecolorallocate($img, mt_rand(0, 120), mt_rand(0, 120), mt_rand(0, 120));
  75. $colors = array();
  76. $minr = mt_rand(20, 30);
  77. $ming = mt_rand(20, 30);
  78. $minb = mt_rand(20, 30);
  79. $maxr = mt_rand(150, 230);
  80. $maxg = mt_rand(150, 230);
  81. $maxb = mt_rand(150, 230);
  82. for ($i = -30; $i <= 30; ++$i)
  83. {
  84. $coeff1 = ($i + 12) / 45;
  85. $coeff2 = 1 - $coeff1;
  86. $colors[$i] = imagecolorallocate($img, ($coeff2 * $maxr) + ($coeff1 * $minr), ($coeff2 * $maxg) + ($coeff1 * $ming), ($coeff2 * $maxb) + ($coeff1 * $minb));
  87. }
  88. // $img_buffer is the last row of 3-space positions (converted to img-space), cached
  89. // (using this means we don't need to recalculate all 4 positions for each new polygon,
  90. // merely the newest point that we're adding, which is then cached.
  91. $img_buffer = array(array(), array());
  92. // In image-space, the x- and y-offset necessary to move one unit in the x-direction in planar-space
  93. $dxx = ($box['upper_right']['x'] - $box['upper_left']['x']) / ($subdivision_factor * $plane_x);
  94. $dxy = ($box['upper_right']['y'] - $box['upper_left']['y']) / ($subdivision_factor * $plane_x);
  95. // In image-space, the x- and y-offset necessary to move one unit in the y-direction in planar-space
  96. $dyx = ($box['lower_right']['x'] - $box['upper_left']['x']) / ($subdivision_factor * $plane_y);
  97. $dyy = ($box['lower_right']['y'] - $box['upper_left']['y']) / ($subdivision_factor * $plane_y);
  98. // Initial captcha-letter offset in planar-space
  99. $plane_offset_x = mt_rand(3, 8);
  100. $plane_offset_y = mt_rand( 12, 15);
  101. // character map
  102. $map = $this->captcha_bitmaps();
  103. // matrix
  104. $plane = array();
  105. // for each character, we'll silkscreen it into our boolean pixel plane
  106. for ($c = 0, $code_num = strlen($code); $c < $code_num; ++$c)
  107. {
  108. $letter = $code[$c];
  109. for ($x = $map['width'] - 1; $x >= 0; --$x)
  110. {
  111. for ($y = $map['height'] - 1; $y >= 0; --$y)
  112. {
  113. if ($map['data'][$letter][$y][$x])
  114. {
  115. $plane[$y + $plane_offset_y + (($c & 1) ? 1 : -1)][$x + $plane_offset_x] = true;
  116. }
  117. }
  118. }
  119. $plane_offset_x += 11;
  120. }
  121. // calculate our first buffer, we can't actually draw polys with these yet
  122. // img_pos_prev == screen x,y location to our immediate left.
  123. // img_pos_cur == current screen x,y location
  124. // we calculate screen position of our
  125. // current cell based on the difference from the previous cell
  126. // rather than recalculating from absolute coordinates
  127. // What we cache into the $img_buffer contains the raised text coordinates.
  128. $img_pos_prev = $img_buffer[0][0] = array($box['upper_left']['x'], $box['upper_left']['y']);
  129. $cur_height = $prev_height = $this->wave_height(0, 0, $subdivision_factor);
  130. $full_x = $plane_x * $subdivision_factor;
  131. $full_y = $plane_y * $subdivision_factor;
  132. for ($x = 1; $x <= $full_x; ++$x)
  133. {
  134. $cur_height = $this->wave_height($x, 0, $subdivision_factor);
  135. $offset = $cur_height - $prev_height;
  136. $img_pos_cur = array($img_pos_prev[0] + $dxx, $img_pos_prev[1] + $dxy + $offset);
  137. $img_buffer[0][$x] = $img_pos_cur;
  138. $img_pos_prev = $img_pos_cur;
  139. $prev_height = $cur_height;
  140. }
  141. for ($y = 1; $y <= $full_y; ++$y)
  142. {
  143. // swap buffers
  144. $buffer_cur = $y & 1;
  145. $buffer_prev = 1 - $buffer_cur;
  146. $prev_height = $this->wave_height(0, $y, $subdivision_factor);
  147. $offset = $prev_height - $this->wave_height(0, $y - 1, $subdivision_factor);
  148. $img_pos_cur = array($img_buffer[$buffer_prev][0][0] + $dyx, min($img_buffer[$buffer_prev][0][1] + $dyy + $offset, $img_y - 1));
  149. // make sure we don't try to write off the page
  150. $img_pos_prev = $img_pos_cur;
  151. $img_buffer[$buffer_cur][0] = $img_pos_cur;
  152. for ($x = 1; $x <= $full_x; ++$x)
  153. {
  154. $cur_height = $this->wave_height($x, $y, $subdivision_factor) + $this->grid_height($x, $y, $x_grid, $y_grid, 1);
  155. // height is a z-factor, not a y-factor
  156. $offset = $cur_height - $prev_height;
  157. $img_pos_cur = array($img_pos_prev[0] + $dxx, $img_pos_prev[1] + $dxy + $offset);
  158. // height is float, index it to an int, get closest color
  159. $color = $colors[intval($cur_height)];
  160. $img_pos_prev = $img_pos_cur;
  161. $prev_height = $cur_height;
  162. $y_index_old = intval(($y - 1) / $subdivision_factor);
  163. $y_index_new = intval($y / $subdivision_factor);
  164. $x_index_old = intval(($x - 1) / $subdivision_factor);
  165. $x_index_new = intval($x / $subdivision_factor);
  166. if (!empty($plane[$y_index_new][$x_index_new]))
  167. {
  168. $img_pos_cur[1] += $this->wave_height($x, $y, $subdivision_factor, 1) - 30 - $cur_height;
  169. $color = $colors[20];
  170. }
  171. $img_pos_cur[1] = min($img_pos_cur[1], $img_y - 1);
  172. $img_buffer[$buffer_cur][$x] = $img_pos_cur;
  173. // Smooth the edges as much as possible by having not more than one low<->high traingle per square
  174. // Otherwise, just
  175. $diag_down = (empty($plane[$y_index_old][$x_index_old]) == empty($plane[$y_index_new][$x_index_new]));
  176. $diag_up = (empty($plane[$y_index_old][$x_index_new]) == empty($plane[$y_index_new][$x_index_old]));
  177. // natural switching
  178. $mode = ($x + $y) & 1;
  179. // override if it requires it
  180. if ($diag_down != $diag_up)
  181. {
  182. $mode = $diag_up;
  183. }
  184. if ($mode)
  185. {
  186. // +-/ /
  187. // 1 |/ 2 /|
  188. // / /-+
  189. $poly1 = array_merge($img_buffer[$buffer_cur][$x - 1], $img_buffer[$buffer_prev][$x - 1], $img_buffer[$buffer_prev][$x]);
  190. $poly2 = array_merge($img_buffer[$buffer_cur][$x - 1], $img_buffer[$buffer_cur][$x], $img_buffer[$buffer_prev][$x]);
  191. }
  192. else
  193. {
  194. // \ \-+
  195. // 1 |\ 2 \|
  196. // +-\ \
  197. $poly1 = array_merge($img_buffer[$buffer_cur][$x - 1], $img_buffer[$buffer_prev][$x - 1], $img_buffer[$buffer_cur][$x]);
  198. $poly2 = array_merge($img_buffer[$buffer_prev][$x - 1], $img_buffer[$buffer_prev][$x], $img_buffer[$buffer_cur][$x]);
  199. }
  200. imagefilledpolygon($img, $poly1, 3, $color);
  201. imagefilledpolygon($img, $poly2, 3, $color);
  202. }
  203. }
  204. // Output image
  205. header('Content-Type: image/png');
  206. header('Cache-control: no-cache, no-store');
  207. //$mtime = explode(' ', microtime());
  208. //$totaltime = $mtime[0] + $mtime[1] - $starttime;
  209. //echo $totaltime . "<br />\n";
  210. //echo memory_get_usage() - $tmp;
  211. imagepng($img);
  212. imagedestroy($img);
  213. }
  214. function wave_height($x, $y, $factor = 1, $tweak = 0.7)
  215. {
  216. // stretch the wave. TODO: pretty it up
  217. $x = $x/5 + 180;
  218. $y = $y/4;
  219. return ((sin($x / (3 * $factor)) + sin($y / (3 * $factor))) * 10 * $tweak);
  220. }
  221. function grid_height($x, $y, $x_grid, $y_grid, $factor = 1)
  222. {
  223. return ((!($x % ($x_grid * $factor)) || !($y % ($y_grid * $factor))) ? 3 : 0);
  224. }
  225. function captcha_bitmaps()
  226. {
  227. return array(
  228. 'width' => 9,
  229. 'height' => 13,
  230. 'data' => array(
  231. 'A' => array(
  232. array(0,0,1,1,1,1,0,0,0),
  233. array(0,1,0,0,0,0,1,0,0),
  234. array(1,0,0,0,0,0,0,1,0),
  235. array(1,0,0,0,0,0,0,1,0),
  236. array(1,0,0,0,0,0,0,1,0),
  237. array(1,0,0,0,0,0,0,1,0),
  238. array(1,0,0,0,0,0,0,1,0),
  239. array(1,1,1,1,1,1,1,1,0),
  240. array(1,0,0,0,0,0,0,1,0),
  241. array(1,0,0,0,0,0,0,1,0),
  242. array(1,0,0,0,0,0,0,1,0),
  243. array(1,0,0,0,0,0,0,1,0),
  244. array(1,0,0,0,0,0,0,1,0),
  245. array(0,0,0,0,0,0,0,0,0),
  246. ),
  247. 'B' => array(
  248. array(1,1,1,1,1,1,0,0,0),
  249. array(1,0,0,0,0,0,1,0,0),
  250. array(1,0,0,0,0,0,0,1,0),
  251. array(1,0,0,0,0,0,0,1,0),
  252. array(1,0,0,0,0,0,0,1,0),
  253. array(1,0,0,0,0,0,1,0,0),
  254. array(1,1,1,1,1,1,0,0,0),
  255. array(1,0,0,0,0,0,1,0,0),
  256. array(1,0,0,0,0,0,0,1,0),
  257. array(1,0,0,0,0,0,0,1,0),
  258. array(1,0,0,0,0,0,0,1,0),
  259. array(1,0,0,0,0,0,1,0,0),
  260. array(1,1,1,1,1,1,0,0,0),
  261. array(0,0,0,0,0,0,0,0,0),
  262. ),
  263. 'C' => array(
  264. array(0,0,1,1,1,1,1,0,0),
  265. array(0,1,0,0,0,0,0,1,0),
  266. array(1,0,0,0,0,0,0,0,1),
  267. array(1,0,0,0,0,0,0,0,0),
  268. array(1,0,0,0,0,0,0,0,0),
  269. array(1,0,0,0,0,0,0,0,0),
  270. array(1,0,0,0,0,0,0,0,0),
  271. array(1,0,0,0,0,0,0,0,0),
  272. array(1,0,0,0,0,0,0,0,0),
  273. array(1,0,0,0,0,0,0,0,1),
  274. array(0,1,0,0,0,0,0,1,0),
  275. array(0,0,1,1,1,1,1,0,0),
  276. array(0,0,0,0,0,0,0,0,0),
  277. array(0,0,0,0,0,0,0,0,0),
  278. ),
  279. 'D' => array(
  280. array(1,1,1,1,1,1,1,0,0),
  281. array(1,0,0,0,0,0,0,1,0),
  282. array(1,0,0,0,0,0,0,0,1),
  283. array(1,0,0,0,0,0,0,0,1),
  284. array(1,0,0,0,0,0,0,0,1),
  285. array(1,0,0,0,0,0,0,0,1),
  286. array(1,0,0,0,0,0,0,0,1),
  287. array(1,0,0,0,0,0,0,0,1),
  288. array(1,0,0,0,0,0,0,0,1),
  289. array(1,0,0,0,0,0,0,1,0),
  290. array(1,1,1,1,1,1,1,0,0),
  291. array(0,0,0,0,0,0,0,0,0),
  292. array(0,0,0,0,0,0,0,0,0),
  293. array(0,0,0,0,0,0,0,0,0),
  294. ),
  295. 'E' => array(
  296. array(0,0,1,1,1,1,1,1,1),
  297. array(0,1,0,0,0,0,0,0,0),
  298. array(1,0,0,0,0,0,0,0,0),
  299. array(1,0,0,0,0,0,0,0,0),
  300. array(1,0,0,0,0,0,0,0,0),
  301. array(1,1,1,1,1,1,1,0,0),
  302. array(1,0,0,0,0,0,0,0,0),
  303. array(1,0,0,0,0,0,0,0,0),
  304. array(1,0,0,0,0,0,0,0,0),
  305. array(0,1,0,0,0,0,0,0,0),
  306. array(0,0,1,1,1,1,1,1,1),
  307. array(0,0,0,0,0,0,0,0,0),
  308. array(0,0,0,0,0,0,0,0,0),
  309. array(0,0,0,0,0,0,0,0,0),
  310. ),
  311. 'F' => array(
  312. array(0,0,1,1,1,1,1,1,0),
  313. array(0,1,0,0,0,0,0,0,0),
  314. array(1,0,0,0,0,0,0,0,0),
  315. array(1,0,0,0,0,0,0,0,0),
  316. array(1,0,0,0,0,0,0,0,0),
  317. array(1,1,1,1,1,1,0,0,0),
  318. array(1,0,0,0,0,0,0,0,0),
  319. array(1,0,0,0,0,0,0,0,0),
  320. array(1,0,0,0,0,0,0,0,0),
  321. array(1,0,0,0,0,0,0,0,0),
  322. array(1,0,0,0,0,0,0,0,0),
  323. array(1,0,0,0,0,0,0,0,0),
  324. array(0,0,0,0,0,0,0,0,0),
  325. array(0,0,0,0,0,0,0,0,0),
  326. ),
  327. 'G' => array(
  328. array(0,0,1,1,1,1,1,0,0),
  329. array(0,1,0,0,0,0,0,1,0),
  330. array(1,0,0,0,0,0,0,0,1),
  331. array(1,0,0,0,0,0,0,0,1),
  332. array(1,0,0,0,0,0,0,0,0),
  333. array(1,0,0,0,0,0,0,0,0),
  334. array(1,0,0,0,0,0,0,0,0),
  335. array(1,0,0,0,0,0,0,1,1),
  336. array(1,0,0,0,0,0,0,0,1),
  337. array(1,0,0,0,0,0,0,0,1),
  338. array(0,1,0,0,0,0,0,1,0),
  339. array(0,0,1,1,1,1,1,0,0),
  340. array(0,0,0,0,0,0,0,0,0),
  341. array(0,0,0,0,0,0,0,0,0),
  342. ),
  343. 'H' => array(
  344. array(1,0,0,0,0,0,1,0,0),
  345. array(1,0,0,0,0,0,1,0,0),
  346. array(1,0,0,0,0,0,1,0,0),
  347. array(1,0,0,0,0,0,1,0,0),
  348. array(1,0,0,0,0,0,1,0,0),
  349. array(1,1,1,1,1,1,1,0,0),
  350. array(1,0,0,0,0,0,1,0,0),
  351. array(1,0,0,0,0,0,1,0,0),
  352. array(1,0,0,0,0,0,1,0,0),
  353. array(1,0,0,0,0,0,1,0,0),
  354. array(1,0,0,0,0,0,1,0,0),
  355. array(0,0,0,0,0,0,0,0,0),
  356. array(0,0,0,0,0,0,0,0,0),
  357. array(0,0,0,0,0,0,0,0,0),
  358. ),
  359. 'I' => array(
  360. array(0,1,1,1,1,1,1,1,0),
  361. array(0,0,0,0,1,0,0,0,0),
  362. array(0,0,0,0,1,0,0,0,0),
  363. array(0,0,0,0,1,0,0,0,0),
  364. array(0,0,0,0,1,0,0,0,0),
  365. array(0,0,0,0,1,0,0,0,0),
  366. array(0,0,0,0,1,0,0,0,0),
  367. array(0,0,0,0,1,0,0,0,0),
  368. array(0,0,0,0,1,0,0,0,0),
  369. array(0,1,1,1,1,1,1,1,0),
  370. array(0,0,0,0,0,0,0,0,0),
  371. array(0,0,0,0,0,0,0,0,0),
  372. array(0,0,0,0,0,0,0,0,0),
  373. array(0,0,0,0,0,0,0,0,0),
  374. ),
  375. 'J' => array(
  376. array(0,0,0,0,0,0,1,1,1),
  377. array(0,0,0,0,0,0,0,0,1),
  378. array(0,0,0,0,0,0,0,0,1),
  379. array(0,0,0,0,0,0,0,0,1),
  380. array(0,0,0,0,0,0,0,0,1),
  381. array(0,0,0,0,0,0,0,0,1),
  382. array(0,0,0,0,0,0,0,0,1),
  383. array(0,1,0,0,0,0,0,0,1),
  384. array(0,1,0,0,0,0,0,0,1),
  385. array(0,0,1,0,0,0,0,1,0),
  386. array(0,0,0,1,1,1,1,0,0),
  387. array(0,0,0,0,0,0,0,0,0),
  388. array(0,0,0,0,0,0,0,0,0),
  389. array(0,0,0,0,0,0,0,0,0),
  390. ),
  391. 'K' => array(
  392. array(1,0,0,0,0,0,1,0,0),
  393. array(1,0,0,0,0,1,0,0,0),
  394. array(1,0,0,0,1,0,0,0,0),
  395. array(1,0,0,1,0,0,0,0,0),
  396. array(1,0,1,0,0,0,0,0,0),
  397. array(1,1,0,0,0,0,0,0,0),
  398. array(1,0,1,0,0,0,0,0,0),
  399. array(1,0,0,1,0,0,0,0,0),
  400. array(1,0,0,0,1,0,0,0,0),
  401. array(1,0,0,0,0,1,0,0,0),
  402. array(1,0,0,0,0,0,1,0,0),
  403. array(0,0,0,0,0,0,0,0,0),
  404. array(0,0,0,0,0,0,0,0,0),
  405. array(0,0,0,0,0,0,0,0,0),
  406. ),
  407. 'L' => array(
  408. array(1,0,0,0,0,0,0,0,0),
  409. array(1,0,0,0,0,0,0,0,0),
  410. array(1,0,0,0,0,0,0,0,0),
  411. array(1,0,0,0,0,0,0,0,0),
  412. array(1,0,0,0,0,0,0,0,0),
  413. array(1,0,0,0,0,0,0,0,0),
  414. array(1,0,0,0,0,0,0,0,0),
  415. array(1,0,0,0,0,0,0,0,0),
  416. array(1,0,0,0,0,0,0,0,0),
  417. array(0,1,0,0,0,0,0,0,0),
  418. array(0,0,1,1,1,1,0,0,0),
  419. array(0,0,0,0,0,0,0,0,0),
  420. array(0,0,0,0,0,0,0,0,0),
  421. array(0,0,0,0,0,0,0,0,0),
  422. ),
  423. 'M' => array(
  424. array(0,1,0,0,0,0,0,1,0),
  425. array(0,1,1,0,0,0,1,1,0),
  426. array(0,1,0,1,0,1,0,1,0),
  427. array(0,1,0,0,1,0,0,1,0),
  428. array(0,1,0,0,0,0,0,1,0),
  429. array(0,1,0,0,0,0,0,1,0),
  430. array(0,1,0,0,0,0,0,1,0),
  431. array(0,1,0,0,0,0,0,1,0),
  432. array(0,1,0,0,0,0,0,1,0),
  433. array(0,0,0,0,0,0,0,0,0),
  434. array(0,0,0,0,0,0,0,0,0),
  435. array(0,0,0,0,0,0,0,0,0),
  436. array(0,0,0,0,0,0,0,0,0),
  437. array(0,0,0,0,0,0,0,0,0),
  438. ),
  439. 'N' => array(
  440. array(1,0,0,0,0,0,0,0,1),
  441. array(1,1,0,0,0,0,0,0,1),
  442. array(1,0,1,0,0,0,0,0,1),
  443. array(1,0,0,1,0,0,0,0,1),
  444. array(1,0,0,0,1,0,0,0,1),
  445. array(1,0,0,0,0,1,0,0,1),
  446. array(1,0,0,0,0,0,1,0,1),
  447. array(1,0,0,0,0,0,0,1,1),
  448. array(1,0,0,0,0,0,0,0,1),
  449. array(0,0,0,0,0,0,0,0,0),
  450. array(0,0,0,0,0,0,0,0,0),
  451. array(0,0,0,0,0,0,0,0,0),
  452. array(0,0,0,0,0,0,0,0,0),
  453. array(0,0,0,0,0,0,0,0,0),
  454. ),
  455. 'O' => array(
  456. array(0,0,0,1,1,1,0,0,0),
  457. array(0,0,1,0,0,0,1,0,0),
  458. array(0,1,0,0,0,0,0,1,0),
  459. array(1,0,0,0,0,0,0,0,1),
  460. array(1,0,0,0,0,0,0,0,1),
  461. array(1,0,0,0,0,0,0,0,1),
  462. array(1,0,0,0,0,0,0,0,1),
  463. array(1,0,0,0,0,0,0,0,1),
  464. array(0,1,0,0,0,0,0,1,0),
  465. array(0,0,1,0,0,0,1,0,0),
  466. array(0,0,0,1,1,1,0,0,0),
  467. array(0,0,0,0,0,0,0,0,0),
  468. array(0,0,0,0,0,0,0,0,0),
  469. array(0,0,0,0,0,0,0,0,0),
  470. ),
  471. 'P' => array(
  472. array(1,1,1,1,1,1,0,0,0),
  473. array(1,0,0,0,0,0,1,0,0),
  474. array(1,0,0,0,0,0,0,1,0),
  475. array(1,0,0,0,0,0,0,1,0),
  476. array(1,0,0,0,0,0,0,1,0),
  477. array(1,0,0,0,0,0,0,1,0),
  478. array(1,0,0,0,0,0,1,0,0),
  479. array(1,1,1,1,1,1,0,0,0),
  480. array(1,0,0,0,0,0,0,0,0),
  481. array(1,0,0,0,0,0,0,0,0),
  482. array(1,0,0,0,0,0,0,0,0),
  483. array(1,0,0,0,0,0,0,0,0),
  484. array(1,0,0,0,0,0,0,0,0),
  485. array(0,0,0,0,0,0,0,0,0),
  486. ),
  487. 'Q' => array(
  488. array(0,0,1,1,1,1,0,0,0),
  489. array(0,1,0,0,0,0,1,0,0),
  490. array(1,0,0,0,0,0,0,1,0),
  491. array(1,0,0,0,0,0,0,1,0),
  492. array(1,0,0,0,0,0,0,1,0),
  493. array(1,0,0,0,0,0,0,1,0),
  494. array(1,0,0,0,1,0,0,1,0),
  495. array(1,0,0,0,0,1,0,1,0),
  496. array(0,1,0,0,0,0,1,0,0),
  497. array(0,0,1,1,1,1,0,1,0),
  498. array(0,0,0,0,0,0,0,0,1),
  499. array(0,0,0,0,0,0,0,0,0),
  500. array(0,0,0,0,0,0,0,0,0),
  501. array(0,0,0,0,0,0,0,0,0),
  502. ),
  503. 'R' => array(
  504. array(1,1,1,1,1,1,0,0,0),
  505. array(1,0,0,0,0,0,1,0,0),
  506. array(1,0,0,0,0,0,0,1,0),
  507. array(1,0,0,0,0,0,0,1,0),
  508. array(1,0,0,0,0,0,0,1,0),
  509. array(1,0,0,0,0,0,1,0,0),
  510. array(1,1,1,1,1,1,0,0,0),
  511. array(1,0,1,0,0,0,0,0,0),
  512. array(1,0,0,1,0,0,0,0,0),
  513. array(1,0,0,0,1,0,0,0,0),
  514. array(1,0,0,0,0,1,0,0,0),
  515. array(1,0,0,0,0,0,1,0,0),
  516. array(0,0,0,0,0,0,0,0,0),
  517. array(0,0,0,0,0,0,0,0,0),
  518. ),
  519. 'S' => array(
  520. array(0,0,1,1,1,1,1,1,1),
  521. array(0,1,0,0,0,0,0,0,0),
  522. array(1,0,0,0,0,0,0,0,0),
  523. array(1,0,0,0,0,0,0,0,0),
  524. array(1,0,0,0,0,0,0,0,0),
  525. array(0,1,0,0,0,0,0,0,0),
  526. array(0,0,1,1,1,1,1,0,0),
  527. array(0,0,0,0,0,0,0,1,0),
  528. array(0,0,0,0,0,0,0,0,1),
  529. array(0,0,0,0,0,0,0,0,1),
  530. array(0,0,0,0,0,0,0,1,0),
  531. array(1,1,1,1,1,1,1,0,0),
  532. array(0,0,0,0,0,0,0,0,0),
  533. array(0,0,0,0,0,0,0,0,0),
  534. ),
  535. 'T' => array(
  536. array(1,1,1,1,1,1,1,1,1),
  537. array(0,0,0,0,1,0,0,0,0),
  538. array(0,0,0,0,1,0,0,0,0),
  539. array(0,0,0,0,1,0,0,0,0),
  540. array(0,0,0,0,1,0,0,0,0),
  541. array(0,0,0,0,1,0,0,0,0),
  542. array(0,0,0,0,1,0,0,0,0),
  543. array(0,0,0,0,1,0,0,0,0),
  544. array(0,0,0,0,1,0,0,0,0),
  545. array(0,0,0,0,1,0,0,0,0),
  546. array(0,0,0,0,1,0,0,0,0),
  547. array(0,0,0,0,0,0,0,0,0),
  548. array(0,0,0,0,0,0,0,0,0),
  549. array(0,0,0,0,0,0,0,0,0),
  550. ),
  551. 'U' => array(
  552. array(1,0,0,0,0,0,0,0,1),
  553. array(1,0,0,0,0,0,0,0,1),
  554. array(1,0,0,0,0,0,0,0,1),
  555. array(1,0,0,0,0,0,0,0,1),
  556. array(1,0,0,0,0,0,0,0,1),
  557. array(1,0,0,0,0,0,0,0,1),
  558. array(1,0,0,0,0,0,0,0,1),
  559. array(1,0,0,0,0,0,0,0,1),
  560. array(1,0,0,0,0,0,0,0,1),
  561. array(0,1,0,0,0,0,0,1,0),
  562. array(0,0,1,1,1,1,1,0,0),
  563. array(0,0,0,0,0,0,0,0,0),
  564. array(0,0,0,0,0,0,0,0,0),
  565. array(0,0,0,0,0,0,0,0,0),
  566. ),
  567. 'V' => array(
  568. array(1,0,0,0,0,0,0,0,1),
  569. array(1,0,0,0,0,0,0,0,1),
  570. array(1,0,0,0,0,0,0,0,1),
  571. array(1,0,0,0,0,0,0,0,1),
  572. array(1,0,0,0,0,0,0,0,1),
  573. array(1,0,0,0,0,0,0,0,1),
  574. array(1,0,0,0,0,0,0,0,1),
  575. array(0,1,0,0,0,0,0,1,0),
  576. array(0,0,1,0,0,0,1,0,0),
  577. array(0,0,0,1,0,1,0,0,0),
  578. array(0,0,0,0,1,0,0,0,0),
  579. array(0,0,0,0,0,0,0,0,0),
  580. array(0,0,0,0,0,0,0,0,0),
  581. array(0,0,0,0,0,0,0,0,0),
  582. ),
  583. 'W' => array(
  584. array(1,0,0,0,0,0,0,0,1),
  585. array(1,0,0,0,0,0,0,0,1),
  586. array(1,0,0,0,0,0,0,0,1),
  587. array(1,0,0,0,0,0,0,0,1),
  588. array(1,0,0,0,1,0,0,0,1),
  589. array(1,0,0,1,0,1,0,0,1),
  590. array(1,0,1,0,0,0,1,0,1),
  591. array(1,1,0,0,0,0,0,1,1),
  592. array(1,0,0,0,0,0,0,0,1),
  593. array(0,0,0,0,0,0,0,0,0),
  594. array(0,0,0,0,0,0,0,0,0),
  595. array(0,0,0,0,0,0,0,0,0),
  596. array(0,0,0,0,0,0,0,0,0),
  597. array(0,0,0,0,0,0,0,0,0),
  598. ),
  599. 'X' => array(
  600. array(1,0,0,0,0,0,0,0,1),
  601. array(1,0,0,0,0,0,0,0,1),
  602. array(0,1,0,0,0,0,0,1,0),
  603. array(0,0,1,0,0,0,1,0,0),
  604. array(0,0,0,1,0,1,0,0,0),
  605. array(0,0,0,0,1,0,0,0,0),
  606. array(0,0,0,1,0,1,0,0,0),
  607. array(0,0,1,0,0,0,1,0,0),
  608. array(0,1,0,0,0,0,0,1,0),
  609. array(1,0,0,0,0,0,0,0,1),
  610. array(1,0,0,0,0,0,0,0,1),
  611. array(0,0,0,0,0,0,0,0,0),
  612. array(0,0,0,0,0,0,0,0,0),
  613. array(0,0,0,0,0,0,0,0,0),
  614. ),
  615. 'Y' => array(
  616. array(1,0,0,0,0,0,0,0,1),
  617. array(1,0,0,0,0,0,0,0,1),
  618. array(1,0,0,0,0,0,0,0,1),
  619. array(0,1,0,0,0,0,0,1,0),
  620. array(0,0,1,0,0,0,1,0,0),
  621. array(0,0,0,1,0,1,0,0,0),
  622. array(0,0,0,0,1,0,0,0,0),
  623. array(0,0,0,0,1,0,0,0,0),
  624. array(0,0,0,0,1,0,0,0,0),
  625. array(0,0,0,0,1,0,0,0,0),
  626. array(0,0,0,0,1,0,0,0,0),
  627. array(0,0,0,0,0,0,0,0,0),
  628. array(0,0,0,0,0,0,0,0,0),
  629. array(0,0,0,0,0,0,0,0,0),
  630. ),
  631. 'Z' => array(
  632. array(1,1,1,1,1,1,1,1,1),
  633. array(1,0,0,0,0,0,0,0,1),
  634. array(0,0,0,0,0,0,0,1,0),
  635. array(0,0,0,0,0,0,1,0,0),
  636. array(0,0,0,0,0,1,0,0,0),
  637. array(0,0,0,0,1,0,0,0,0),
  638. array(0,0,0,1,0,0,0,0,0),
  639. array(0,0,1,0,0,0,0,0,0),
  640. array(0,1,0,0,0,0,0,0,0),
  641. array(1,0,0,0,0,0,0,0,1),
  642. array(1,1,1,1,1,1,1,1,1),
  643. array(0,0,0,0,0,0,0,0,0),
  644. array(0,0,0,0,0,0,0,0,0),
  645. array(0,0,0,0,0,0,0,0,0),
  646. ),
  647. '1' => array(
  648. array(0,0,0,0,1,0,0,0,0),
  649. array(0,0,0,1,1,0,0,0,0),
  650. array(0,0,1,0,1,0,0,0,0),
  651. array(0,1,0,0,1,0,0,0,0),
  652. array(0,0,0,0,1,0,0,0,0),
  653. array(0,0,0,0,1,0,0,0,0),
  654. array(0,0,0,0,1,0,0,0,0),
  655. array(0,0,0,0,1,0,0,0,0),
  656. array(0,0,0,0,1,0,0,0,0),
  657. array(0,0,0,0,1,0,0,0,0),
  658. array(0,0,0,0,1,0,0,0,0),
  659. array(0,1,1,1,1,1,1,1,0),
  660. array(0,0,0,0,0,0,0,0,0),
  661. array(0,0,0,0,0,0,0,0,0),
  662. ),
  663. '2' => array(
  664. array(0,0,0,1,1,1,0,0,0),
  665. array(0,0,1,0,0,0,1,0,0),
  666. array(0,1,0,0,0,0,0,1,0),
  667. array(0,0,0,0,0,0,0,0,1),
  668. array(0,0,0,0,0,0,0,0,1),
  669. array(0,0,0,0,0,0,0,0,1),
  670. array(0,0,0,0,0,0,0,1,0),
  671. array(0,0,0,0,0,0,1,0,0),
  672. array(0,0,0,0,0,1,0,0,0),
  673. array(0,0,0,0,1,0,0,0,0),
  674. array(0,0,0,1,0,0,0,0,0),
  675. array(0,0,1,0,0,0,0,0,0),
  676. array(0,1,1,1,1,1,1,1,1),
  677. array(0,0,0,0,0,0,0,0,0),
  678. ),
  679. '3' => array(
  680. array(0,0,0,1,1,1,1,0,0),
  681. array(0,0,1,0,0,0,0,1,0),
  682. array(0,1,0,0,0,0,0,0,1),
  683. array(0,0,0,0,0,0,0,0,1),
  684. array(0,0,0,0,0,0,0,0,1),
  685. array(0,0,0,0,0,0,0,1,0),
  686. array(0,0,0,0,0,1,1,0,0),
  687. array(0,0,0,0,0,0,0,1,0),
  688. array(0,0,0,0,0,0,0,0,1),
  689. array(0,0,0,0,0,0,0,0,1),
  690. array(0,1,0,0,0,0,0,0,1),
  691. array(0,0,1,0,0,0,0,1,0),
  692. array(0,0,0,1,1,1,1,0,0),
  693. array(0,0,0,0,0,0,0,0,0),
  694. ),
  695. '4' => array(
  696. array(0,0,0,0,0,0,0,1,0),
  697. array(0,0,0,0,0,0,1,1,0),
  698. array(0,0,0,0,0,1,0,1,0),
  699. array(0,0,0,0,1,0,0,1,0),
  700. array(0,0,0,1,0,0,0,1,0),
  701. array(0,0,1,0,0,0,0,1,0),
  702. array(0,1,1,1,1,1,1,1,1),
  703. array(0,0,0,0,0,0,0,1,0),
  704. array(0,0,0,0,0,0,0,1,0),
  705. array(0,0,0,0,0,0,0,1,0),
  706. array(0,0,0,0,0,0,0,1,0),
  707. array(0,0,0,0,0,0,0,0,0),
  708. array(0,0,0,0,0,0,0,0,0),
  709. array(0,0,0,0,0,0,0,0,0),
  710. ),
  711. '5' => array(
  712. array(1,1,1,1,1,1,1,1,1),
  713. array(1,0,0,0,0,0,0,0,0),
  714. array(1,0,0,0,0,0,0,0,0),
  715. array(1,0,0,0,0,0,0,0,0),
  716. array(0,1,0,0,0,0,0,0,0),
  717. array(0,0,1,1,1,1,1,0,0),
  718. array(0,0,0,0,0,0,0,1,0),
  719. array(0,0,0,0,0,0,0,0,1),
  720. array(1,0,0,0,0,0,0,0,1),
  721. array(0,1,0,0,0,0,0,1,0),
  722. array(0,0,1,1,1,1,1,0,0),
  723. array(0,0,0,0,0,0,0,0,0),
  724. array(0,0,0,0,0,0,0,0,0),
  725. array(0,0,0,0,0,0,0,0,0),
  726. ),
  727. '6' => array(
  728. array(0,0,1,1,1,1,1,0,0),
  729. array(0,1,0,0,0,0,0,1,0),
  730. array(1,0,0,0,0,0,0,0,1),
  731. array(1,0,0,0,0,0,0,0,0),
  732. array(1,0,0,0,0,0,0,0,0),
  733. array(1,0,0,1,1,1,1,0,0),
  734. array(1,0,1,0,0,0,0,1,0),
  735. array(1,1,0,0,0,0,0,0,1),
  736. array(1,0,0,0,0,0,0,0,1),
  737. array(1,0,0,0,0,0,0,0,1),
  738. array(0,1,0,0,0,0,0,1,0),
  739. array(0,0,1,1,1,1,1,0,0),
  740. array(0,0,0,0,0,0,0,0,0),
  741. array(0,0,0,0,0,0,0,0,0),
  742. array(0,0,0,0,0,0,0,0,0),
  743. ),
  744. '7' => array(
  745. array(1,1,1,1,1,1,1,1,1),
  746. array(1,0,0,0,0,0,0,0,1),
  747. array(0,0,0,0,0,0,0,1,0),
  748. array(0,0,0,0,0,0,1,0,0),
  749. array(0,0,0,0,0,1,0,0,0),
  750. array(0,0,0,0,1,0,0,0,0),
  751. array(0,0,0,0,1,0,0,0,0),
  752. array(0,0,0,0,1,0,0,0,0),
  753. array(0,0,0,0,1,0,0,0,0),
  754. array(0,0,0,0,1,0,0,0,0),
  755. array(0,0,0,0,1,0,0,0,0),
  756. array(0,0,0,0,0,0,0,0,0),
  757. array(0,0,0,0,0,0,0,0,0),
  758. array(0,0,0,0,0,0,0,0,0),
  759. ),
  760. '8' => array(
  761. array(0,0,1,1,1,1,1,0,0),
  762. array(0,1,0,0,0,0,0,1,0),
  763. array(1,0,0,0,0,0,0,0,1),
  764. array(1,0,0,0,0,0,0,0,1),
  765. array(1,0,0,0,0,0,0,0,1),
  766. array(0,1,0,0,0,0,0,1,0),
  767. array(0,0,1,1,1,1,1,0,0),
  768. array(0,1,0,0,0,0,0,1,0),
  769. array(1,0,0,0,0,0,0,0,1),
  770. array(1,0,0,0,0,0,0,0,1),
  771. array(1,0,0,0,0,0,0,0,1),
  772. array(0,1,0,0,0,0,0,1,0),
  773. array(0,0,1,1,1,1,1,0,0),
  774. array(0,0,0,0,0,0,0,0,0),
  775. ),
  776. '9' => array(
  777. array(0,0,0,1,1,1,1,0,0),
  778. array(0,0,1,0,0,0,0,1,0),
  779. array(0,1,0,0,0,0,0,0,1),
  780. array(0,1,0,0,0,0,0,0,1),
  781. array(0,1,0,0,0,0,0,0,1),
  782. array(0,1,0,0,0,0,0,1,1),
  783. array(0,0,1,1,1,1,1,0,1),
  784. array(0,0,0,0,0,0,0,0,1),
  785. array(0,0,0,0,0,0,0,0,1),
  786. array(0,1,0,0,0,0,0,0,1),
  787. array(0,0,1,0,0,0,0,1,0),
  788. array(0,0,0,1,1,1,1,0,0),
  789. array(0,0,0,0,0,0,0,0,0),
  790. array(0,0,0,0,0,0,0,0,0),
  791. ),
  792. )
  793. );
  794. }
  795. }