PageRenderTime 54ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/phpBB/includes/captcha/captcha_gd_wave.php

http://github.com/phpbb/phpbb3
PHP | 842 lines | 730 code | 48 blank | 64 comment | 16 complexity | 86defbef2f00c3f373c10c80e7904d75 MD5 | raw file
Possible License(s): AGPL-1.0
  1. <?php
  2. /**
  3. *
  4. * @package VC
  5. * @copyright (c) 2006 phpBB Group
  6. * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
  7. *
  8. */
  9. /**
  10. * Wave3D CAPTCHA
  11. *
  12. * @author Robert Hetzler
  13. * @package VC
  14. */
  15. class captcha
  16. {
  17. var $width = 360;
  18. var $height = 96;
  19. function execute($code, $seed)
  20. {
  21. global $starttime;
  22. // seed the random generator
  23. mt_srand($seed);
  24. // set height and width
  25. $img_x = $this->width;
  26. $img_y = $this->height;
  27. // Generate image
  28. $img = imagecreatetruecolor($img_x, $img_y);
  29. $x_grid = mt_rand(6, 10);
  30. $y_grid = mt_rand(6, 10);
  31. // Ok, so lets cut to the chase. We could accurately represent this in 3d and
  32. // do all the appropriate linear transforms. my questions is... why bother?
  33. // The computational overhead is unnecessary when you consider the simple fact:
  34. // we're not here to accurately represent a model, but to just show off some random-ish
  35. // polygons
  36. // Conceive of 3 spaces.
  37. // 1) planar-space (discrete "pixel" grid)
  38. // 2) 3-space. (planar-space with z/height aspect)
  39. // 3) image space (pixels on the screen)
  40. // resolution of the planar-space we're embedding the text code in
  41. $plane_x = 100;
  42. $plane_y = 30;
  43. $subdivision_factor = 3;
  44. // $box is the 4 points in img_space that correspond to the corners of the plane in 3-space
  45. $box = array(
  46. 'upper_left' => array(
  47. 'x' => mt_rand(5, 15),
  48. 'y' => mt_rand(10, 15)
  49. ),
  50. 'upper_right' => array(
  51. 'x' => mt_rand($img_x - 35, $img_x - 19),
  52. 'y' => mt_rand(10, 17)
  53. ),
  54. 'lower_left' => array(
  55. 'x' => mt_rand($img_x - 45, $img_x - 5),
  56. 'y' => mt_rand($img_y - 15, $img_y - 0),
  57. ),
  58. );
  59. $box['lower_right'] = array(
  60. 'x' => $box['lower_left']['x'] + $box['upper_left']['x'] - $box['upper_right']['x'],
  61. 'y' => $box['lower_left']['y'] + $box['upper_left']['y'] - $box['upper_right']['y'],
  62. );
  63. // TODO
  64. $background = imagecolorallocate($img, mt_rand(155, 255), mt_rand(155, 255), mt_rand(155, 255));
  65. imagefill($img, 0, 0, $background);
  66. $black = imagecolorallocate($img, 0, 0, 0);
  67. $random = array();
  68. $fontcolors = array();
  69. for ($i = 0; $i < 15; ++$i)
  70. {
  71. $random[$i] = imagecolorallocate($img, mt_rand(120, 255), mt_rand(120, 255), mt_rand(120, 255));
  72. }
  73. $fontcolors[0] = imagecolorallocate($img, mt_rand(0, 120), mt_rand(0, 120), mt_rand(0, 120));
  74. $colors = array();
  75. $minr = mt_rand(20, 30);
  76. $ming = mt_rand(20, 30);
  77. $minb = mt_rand(20, 30);
  78. $maxr = mt_rand(150, 230);
  79. $maxg = mt_rand(150, 230);
  80. $maxb = mt_rand(150, 230);
  81. for ($i = -30; $i <= 30; ++$i)
  82. {
  83. $coeff1 = ($i + 12) / 45;
  84. $coeff2 = 1 - $coeff1;
  85. $colors[$i] = imagecolorallocate($img, ($coeff2 * $maxr) + ($coeff1 * $minr), ($coeff2 * $maxg) + ($coeff1 * $ming), ($coeff2 * $maxb) + ($coeff1 * $minb));
  86. }
  87. // $img_buffer is the last row of 3-space positions (converted to img-space), cached
  88. // (using this means we don't need to recalculate all 4 positions for each new polygon,
  89. // merely the newest point that we're adding, which is then cached.
  90. $img_buffer = array(array(), array());
  91. // In image-space, the x- and y-offset necessary to move one unit in the x-direction in planar-space
  92. $dxx = ($box['upper_right']['x'] - $box['upper_left']['x']) / ($subdivision_factor * $plane_x);
  93. $dxy = ($box['upper_right']['y'] - $box['upper_left']['y']) / ($subdivision_factor * $plane_x);
  94. // In image-space, the x- and y-offset necessary to move one unit in the y-direction in planar-space
  95. $dyx = ($box['lower_right']['x'] - $box['upper_left']['x']) / ($subdivision_factor * $plane_y);
  96. $dyy = ($box['lower_right']['y'] - $box['upper_left']['y']) / ($subdivision_factor * $plane_y);
  97. // Initial captcha-letter offset in planar-space
  98. $plane_offset_x = mt_rand(3, 8);
  99. $plane_offset_y = mt_rand( 12, 15);
  100. // character map
  101. $map = $this->captcha_bitmaps();
  102. // matrix
  103. $plane = array();
  104. // for each character, we'll silkscreen it into our boolean pixel plane
  105. for ($c = 0, $code_num = strlen($code); $c < $code_num; ++$c)
  106. {
  107. $letter = $code[$c];
  108. for ($x = $map['width'] - 1; $x >= 0; --$x)
  109. {
  110. for ($y = $map['height'] - 1; $y >= 0; --$y)
  111. {
  112. if ($map['data'][$letter][$y][$x])
  113. {
  114. $plane[$y + $plane_offset_y + (($c & 1) ? 1 : -1)][$x + $plane_offset_x] = true;
  115. }
  116. }
  117. }
  118. $plane_offset_x += 11;
  119. }
  120. // calculate our first buffer, we can't actually draw polys with these yet
  121. // img_pos_prev == screen x,y location to our immediate left.
  122. // img_pos_cur == current screen x,y location
  123. // we calculate screen position of our
  124. // current cell based on the difference from the previous cell
  125. // rather than recalculating from absolute coordinates
  126. // What we cache into the $img_buffer contains the raised text coordinates.
  127. $img_pos_prev = $img_buffer[0][0] = array($box['upper_left']['x'], $box['upper_left']['y']);
  128. $cur_height = $prev_height = $this->wave_height(0, 0, $subdivision_factor);
  129. $full_x = $plane_x * $subdivision_factor;
  130. $full_y = $plane_y * $subdivision_factor;
  131. for ($x = 1; $x <= $full_x; ++$x)
  132. {
  133. $cur_height = $this->wave_height($x, 0, $subdivision_factor);
  134. $offset = $cur_height - $prev_height;
  135. $img_pos_cur = array($img_pos_prev[0] + $dxx, $img_pos_prev[1] + $dxy + $offset);
  136. $img_buffer[0][$x] = $img_pos_cur;
  137. $img_pos_prev = $img_pos_cur;
  138. $prev_height = $cur_height;
  139. }
  140. for ($y = 1; $y <= $full_y; ++$y)
  141. {
  142. // swap buffers
  143. $buffer_cur = $y & 1;
  144. $buffer_prev = 1 - $buffer_cur;
  145. $prev_height = $this->wave_height(0, $y, $subdivision_factor);
  146. $offset = $prev_height - $this->wave_height(0, $y - 1, $subdivision_factor);
  147. $img_pos_cur = array($img_buffer[$buffer_prev][0][0] + $dyx, min($img_buffer[$buffer_prev][0][1] + $dyy + $offset, $img_y - 1));
  148. // make sure we don't try to write off the page
  149. $img_pos_prev = $img_pos_cur;
  150. $img_buffer[$buffer_cur][0] = $img_pos_cur;
  151. for ($x = 1; $x <= $full_x; ++$x)
  152. {
  153. $cur_height = $this->wave_height($x, $y, $subdivision_factor) + $this->grid_height($x, $y, 1, $x_grid, $y_grid);
  154. // height is a z-factor, not a y-factor
  155. $offset = $cur_height - $prev_height;
  156. $img_pos_cur = array($img_pos_prev[0] + $dxx, $img_pos_prev[1] + $dxy + $offset);
  157. // height is float, index it to an int, get closest color
  158. $color = $colors[intval($cur_height)];
  159. $img_pos_prev = $img_pos_cur;
  160. $prev_height = $cur_height;
  161. $y_index_old = intval(($y - 1) / $subdivision_factor);
  162. $y_index_new = intval($y / $subdivision_factor);
  163. $x_index_old = intval(($x - 1) / $subdivision_factor);
  164. $x_index_new = intval($x / $subdivision_factor);
  165. if (!empty($plane[$y_index_new][$x_index_new]))
  166. {
  167. $img_pos_cur[1] += $this->wave_height($x, $y, $subdivision_factor, 1) - 30 - $cur_height;
  168. $color = $colors[20];
  169. }
  170. $img_pos_cur[1] = min($img_pos_cur[1], $img_y - 1);
  171. $img_buffer[$buffer_cur][$x] = $img_pos_cur;
  172. // Smooth the edges as much as possible by having not more than one low<->high traingle per square
  173. // Otherwise, just
  174. $diag_down = (empty($plane[$y_index_old][$x_index_old]) == empty($plane[$y_index_new][$x_index_new]));
  175. $diag_up = (empty($plane[$y_index_old][$x_index_new]) == empty($plane[$y_index_new][$x_index_old]));
  176. // natural switching
  177. $mode = ($x + $y) & 1;
  178. // override if it requires it
  179. if ($diag_down != $diag_up)
  180. {
  181. $mode = $diag_up;
  182. }
  183. if ($mode)
  184. {
  185. // +-/ /
  186. // 1 |/ 2 /|
  187. // / /-+
  188. $poly1 = array_merge($img_buffer[$buffer_cur][$x - 1], $img_buffer[$buffer_prev][$x - 1], $img_buffer[$buffer_prev][$x]);
  189. $poly2 = array_merge($img_buffer[$buffer_cur][$x - 1], $img_buffer[$buffer_cur][$x], $img_buffer[$buffer_prev][$x]);
  190. }
  191. else
  192. {
  193. // \ \-+
  194. // 1 |\ 2 \|
  195. // +-\ \
  196. $poly1 = array_merge($img_buffer[$buffer_cur][$x - 1], $img_buffer[$buffer_prev][$x - 1], $img_buffer[$buffer_cur][$x]);
  197. $poly2 = array_merge($img_buffer[$buffer_prev][$x - 1], $img_buffer[$buffer_prev][$x], $img_buffer[$buffer_cur][$x]);
  198. }
  199. imagefilledpolygon($img, $poly1, 3, $color);
  200. imagefilledpolygon($img, $poly2, 3, $color);
  201. }
  202. }
  203. // Output image
  204. header('Content-Type: image/png');
  205. header('Cache-control: no-cache, no-store');
  206. //$mtime = explode(' ', microtime());
  207. //$totaltime = $mtime[0] + $mtime[1] - $starttime;
  208. //echo $totaltime . "<br />\n";
  209. //echo memory_get_usage() - $tmp;
  210. imagepng($img);
  211. imagedestroy($img);
  212. }
  213. function wave_height($x, $y, $factor = 1, $tweak = 0.7)
  214. {
  215. // stretch the wave. TODO: pretty it up
  216. $x = $x/5 + 180;
  217. $y = $y/4;
  218. return ((sin($x / (3 * $factor)) + sin($y / (3 * $factor))) * 10 * $tweak);
  219. }
  220. function grid_height($x, $y, $factor = 1, $x_grid, $y_grid)
  221. {
  222. return ((!($x % ($x_grid * $factor)) || !($y % ($y_grid * $factor))) ? 3 : 0);
  223. }
  224. function captcha_bitmaps()
  225. {
  226. return array(
  227. 'width' => 9,
  228. 'height' => 13,
  229. 'data' => array(
  230. 'A' => array(
  231. array(0,0,1,1,1,1,0,0,0),
  232. array(0,1,0,0,0,0,1,0,0),
  233. array(1,0,0,0,0,0,0,1,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,1,1,1,1,1,1,1,0),
  239. array(1,0,0,0,0,0,0,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(0,0,0,0,0,0,0,0,0),
  245. ),
  246. 'B' => array(
  247. array(1,1,1,1,1,1,0,0,0),
  248. array(1,0,0,0,0,0,1,0,0),
  249. array(1,0,0,0,0,0,0,1,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,1,0,0),
  253. array(1,1,1,1,1,1,0,0,0),
  254. array(1,0,0,0,0,0,1,0,0),
  255. array(1,0,0,0,0,0,0,1,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,1,0,0),
  259. array(1,1,1,1,1,1,0,0,0),
  260. array(0,0,0,0,0,0,0,0,0),
  261. ),
  262. 'C' => array(
  263. array(0,0,1,1,1,1,1,0,0),
  264. array(0,1,0,0,0,0,0,1,0),
  265. array(1,0,0,0,0,0,0,0,1),
  266. array(1,0,0,0,0,0,0,0,0),
  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,1),
  273. array(0,1,0,0,0,0,0,1,0),
  274. array(0,0,1,1,1,1,1,0,0),
  275. array(0,0,0,0,0,0,0,0,0),
  276. array(0,0,0,0,0,0,0,0,0),
  277. ),
  278. 'D' => array(
  279. array(1,1,1,1,1,1,1,0,0),
  280. array(1,0,0,0,0,0,0,1,0),
  281. array(1,0,0,0,0,0,0,0,1),
  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,1,0),
  289. array(1,1,1,1,1,1,1,0,0),
  290. array(0,0,0,0,0,0,0,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. ),
  294. 'E' => array(
  295. array(0,0,1,1,1,1,1,1,1),
  296. array(0,1,0,0,0,0,0,0,0),
  297. array(1,0,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,1,1,1,1,1,1,0,0),
  301. array(1,0,0,0,0,0,0,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(0,1,0,0,0,0,0,0,0),
  305. array(0,0,1,1,1,1,1,1,1),
  306. array(0,0,0,0,0,0,0,0,0),
  307. array(0,0,0,0,0,0,0,0,0),
  308. array(0,0,0,0,0,0,0,0,0),
  309. ),
  310. 'F' => array(
  311. array(0,0,1,1,1,1,1,1,0),
  312. array(0,1,0,0,0,0,0,0,0),
  313. array(1,0,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,1,1,1,1,1,0,0,0),
  317. array(1,0,0,0,0,0,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(0,0,0,0,0,0,0,0,0),
  324. array(0,0,0,0,0,0,0,0,0),
  325. ),
  326. 'G' => array(
  327. array(0,0,1,1,1,1,1,0,0),
  328. array(0,1,0,0,0,0,0,1,0),
  329. array(1,0,0,0,0,0,0,0,1),
  330. array(1,0,0,0,0,0,0,0,1),
  331. array(1,0,0,0,0,0,0,0,0),
  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,1,1),
  335. array(1,0,0,0,0,0,0,0,1),
  336. array(1,0,0,0,0,0,0,0,1),
  337. array(0,1,0,0,0,0,0,1,0),
  338. array(0,0,1,1,1,1,1,0,0),
  339. array(0,0,0,0,0,0,0,0,0),
  340. array(0,0,0,0,0,0,0,0,0),
  341. ),
  342. 'H' => array(
  343. array(1,0,0,0,0,0,1,0,0),
  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,1,1,1,1,1,1,0,0),
  349. array(1,0,0,0,0,0,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(0,0,0,0,0,0,0,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. ),
  358. 'I' => array(
  359. array(0,1,1,1,1,1,1,1,0),
  360. array(0,0,0,0,1,0,0,0,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,1,1,1,1,1,1,1,0),
  369. array(0,0,0,0,0,0,0,0,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. ),
  374. 'J' => array(
  375. array(0,0,0,0,0,0,1,1,1),
  376. array(0,0,0,0,0,0,0,0,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,1,0,0,0,0,0,0,1),
  383. array(0,1,0,0,0,0,0,0,1),
  384. array(0,0,1,0,0,0,0,1,0),
  385. array(0,0,0,1,1,1,1,0,0),
  386. array(0,0,0,0,0,0,0,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. ),
  390. 'K' => array(
  391. array(1,0,0,0,0,0,1,0,0),
  392. array(1,0,0,0,0,1,0,0,0),
  393. array(1,0,0,0,1,0,0,0,0),
  394. array(1,0,0,1,0,0,0,0,0),
  395. array(1,0,1,0,0,0,0,0,0),
  396. array(1,1,0,0,0,0,0,0,0),
  397. array(1,0,1,0,0,0,0,0,0),
  398. array(1,0,0,1,0,0,0,0,0),
  399. array(1,0,0,0,1,0,0,0,0),
  400. array(1,0,0,0,0,1,0,0,0),
  401. array(1,0,0,0,0,0,1,0,0),
  402. array(0,0,0,0,0,0,0,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. ),
  406. 'L' => array(
  407. array(1,0,0,0,0,0,0,0,0),
  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(0,1,0,0,0,0,0,0,0),
  417. array(0,0,1,1,1,1,0,0,0),
  418. array(0,0,0,0,0,0,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. ),
  422. 'M' => array(
  423. array(0,1,0,0,0,0,0,1,0),
  424. array(0,1,1,0,0,0,1,1,0),
  425. array(0,1,0,1,0,1,0,1,0),
  426. array(0,1,0,0,1,0,0,1,0),
  427. array(0,1,0,0,0,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,0,0,0,0,0,0,0,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. ),
  438. 'N' => array(
  439. array(1,0,0,0,0,0,0,0,1),
  440. array(1,1,0,0,0,0,0,0,1),
  441. array(1,0,1,0,0,0,0,0,1),
  442. array(1,0,0,1,0,0,0,0,1),
  443. array(1,0,0,0,1,0,0,0,1),
  444. array(1,0,0,0,0,1,0,0,1),
  445. array(1,0,0,0,0,0,1,0,1),
  446. array(1,0,0,0,0,0,0,1,1),
  447. array(1,0,0,0,0,0,0,0,1),
  448. array(0,0,0,0,0,0,0,0,0),
  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. ),
  454. 'O' => array(
  455. array(0,0,0,1,1,1,0,0,0),
  456. array(0,0,1,0,0,0,1,0,0),
  457. array(0,1,0,0,0,0,0,1,0),
  458. array(1,0,0,0,0,0,0,0,1),
  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(0,1,0,0,0,0,0,1,0),
  464. array(0,0,1,0,0,0,1,0,0),
  465. array(0,0,0,1,1,1,0,0,0),
  466. array(0,0,0,0,0,0,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. ),
  470. 'P' => array(
  471. array(1,1,1,1,1,1,0,0,0),
  472. array(1,0,0,0,0,0,1,0,0),
  473. array(1,0,0,0,0,0,0,1,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,1,0,0),
  478. array(1,1,1,1,1,1,0,0,0),
  479. array(1,0,0,0,0,0,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(0,0,0,0,0,0,0,0,0),
  485. ),
  486. 'Q' => array(
  487. array(0,0,1,1,1,1,0,0,0),
  488. array(0,1,0,0,0,0,1,0,0),
  489. array(1,0,0,0,0,0,0,1,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,1,0,0,1,0),
  494. array(1,0,0,0,0,1,0,1,0),
  495. array(0,1,0,0,0,0,1,0,0),
  496. array(0,0,1,1,1,1,0,1,0),
  497. array(0,0,0,0,0,0,0,0,1),
  498. array(0,0,0,0,0,0,0,0,0),
  499. array(0,0,0,0,0,0,0,0,0),
  500. array(0,0,0,0,0,0,0,0,0),
  501. ),
  502. 'R' => array(
  503. array(1,1,1,1,1,1,0,0,0),
  504. array(1,0,0,0,0,0,1,0,0),
  505. array(1,0,0,0,0,0,0,1,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,1,0,0),
  509. array(1,1,1,1,1,1,0,0,0),
  510. array(1,0,1,0,0,0,0,0,0),
  511. array(1,0,0,1,0,0,0,0,0),
  512. array(1,0,0,0,1,0,0,0,0),
  513. array(1,0,0,0,0,1,0,0,0),
  514. array(1,0,0,0,0,0,1,0,0),
  515. array(0,0,0,0,0,0,0,0,0),
  516. array(0,0,0,0,0,0,0,0,0),
  517. ),
  518. 'S' => array(
  519. array(0,0,1,1,1,1,1,1,1),
  520. array(0,1,0,0,0,0,0,0,0),
  521. array(1,0,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(0,1,0,0,0,0,0,0,0),
  525. array(0,0,1,1,1,1,1,0,0),
  526. array(0,0,0,0,0,0,0,1,0),
  527. array(0,0,0,0,0,0,0,0,1),
  528. array(0,0,0,0,0,0,0,0,1),
  529. array(0,0,0,0,0,0,0,1,0),
  530. array(1,1,1,1,1,1,1,0,0),
  531. array(0,0,0,0,0,0,0,0,0),
  532. array(0,0,0,0,0,0,0,0,0),
  533. ),
  534. 'T' => array(
  535. array(1,1,1,1,1,1,1,1,1),
  536. array(0,0,0,0,1,0,0,0,0),
  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,0,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. ),
  550. 'U' => array(
  551. array(1,0,0,0,0,0,0,0,1),
  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(0,1,0,0,0,0,0,1,0),
  561. array(0,0,1,1,1,1,1,0,0),
  562. array(0,0,0,0,0,0,0,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. ),
  566. 'V' => array(
  567. array(1,0,0,0,0,0,0,0,1),
  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(0,1,0,0,0,0,0,1,0),
  575. array(0,0,1,0,0,0,1,0,0),
  576. array(0,0,0,1,0,1,0,0,0),
  577. array(0,0,0,0,1,0,0,0,0),
  578. array(0,0,0,0,0,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. ),
  582. 'W' => array(
  583. array(1,0,0,0,0,0,0,0,1),
  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,1,0,0,0,1),
  588. array(1,0,0,1,0,1,0,0,1),
  589. array(1,0,1,0,0,0,1,0,1),
  590. array(1,1,0,0,0,0,0,1,1),
  591. array(1,0,0,0,0,0,0,0,1),
  592. array(0,0,0,0,0,0,0,0,0),
  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. ),
  598. 'X' => array(
  599. array(1,0,0,0,0,0,0,0,1),
  600. array(1,0,0,0,0,0,0,0,1),
  601. array(0,1,0,0,0,0,0,1,0),
  602. array(0,0,1,0,0,0,1,0,0),
  603. array(0,0,0,1,0,1,0,0,0),
  604. array(0,0,0,0,1,0,0,0,0),
  605. array(0,0,0,1,0,1,0,0,0),
  606. array(0,0,1,0,0,0,1,0,0),
  607. array(0,1,0,0,0,0,0,1,0),
  608. array(1,0,0,0,0,0,0,0,1),
  609. array(1,0,0,0,0,0,0,0,1),
  610. array(0,0,0,0,0,0,0,0,0),
  611. array(0,0,0,0,0,0,0,0,0),
  612. array(0,0,0,0,0,0,0,0,0),
  613. ),
  614. 'Y' => array(
  615. array(1,0,0,0,0,0,0,0,1),
  616. array(1,0,0,0,0,0,0,0,1),
  617. array(1,0,0,0,0,0,0,0,1),
  618. array(0,1,0,0,0,0,0,1,0),
  619. array(0,0,1,0,0,0,1,0,0),
  620. array(0,0,0,1,0,1,0,0,0),
  621. array(0,0,0,0,1,0,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,0,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. ),
  630. 'Z' => array(
  631. array(1,1,1,1,1,1,1,1,1),
  632. array(1,0,0,0,0,0,0,0,1),
  633. array(0,0,0,0,0,0,0,1,0),
  634. array(0,0,0,0,0,0,1,0,0),
  635. array(0,0,0,0,0,1,0,0,0),
  636. array(0,0,0,0,1,0,0,0,0),
  637. array(0,0,0,1,0,0,0,0,0),
  638. array(0,0,1,0,0,0,0,0,0),
  639. array(0,1,0,0,0,0,0,0,0),
  640. array(1,0,0,0,0,0,0,0,1),
  641. array(1,1,1,1,1,1,1,1,1),
  642. array(0,0,0,0,0,0,0,0,0),
  643. array(0,0,0,0,0,0,0,0,0),
  644. array(0,0,0,0,0,0,0,0,0),
  645. ),
  646. '1' => array(
  647. array(0,0,0,0,1,0,0,0,0),
  648. array(0,0,0,1,1,0,0,0,0),
  649. array(0,0,1,0,1,0,0,0,0),
  650. array(0,1,0,0,1,0,0,0,0),
  651. array(0,0,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,1,1,1,1,1,1,1,0),
  659. array(0,0,0,0,0,0,0,0,0),
  660. array(0,0,0,0,0,0,0,0,0),
  661. ),
  662. '2' => array(
  663. array(0,0,0,1,1,1,0,0,0),
  664. array(0,0,1,0,0,0,1,0,0),
  665. array(0,1,0,0,0,0,0,1,0),
  666. array(0,0,0,0,0,0,0,0,1),
  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,1,0),
  670. array(0,0,0,0,0,0,1,0,0),
  671. array(0,0,0,0,0,1,0,0,0),
  672. array(0,0,0,0,1,0,0,0,0),
  673. array(0,0,0,1,0,0,0,0,0),
  674. array(0,0,1,0,0,0,0,0,0),
  675. array(0,1,1,1,1,1,1,1,1),
  676. array(0,0,0,0,0,0,0,0,0),
  677. ),
  678. '3' => array(
  679. array(0,0,0,1,1,1,1,0,0),
  680. array(0,0,1,0,0,0,0,1,0),
  681. array(0,1,0,0,0,0,0,0,1),
  682. array(0,0,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,1,0),
  685. array(0,0,0,0,0,1,1,0,0),
  686. array(0,0,0,0,0,0,0,1,0),
  687. array(0,0,0,0,0,0,0,0,1),
  688. array(0,0,0,0,0,0,0,0,1),
  689. array(0,1,0,0,0,0,0,0,1),
  690. array(0,0,1,0,0,0,0,1,0),
  691. array(0,0,0,1,1,1,1,0,0),
  692. array(0,0,0,0,0,0,0,0,0),
  693. ),
  694. '4' => array(
  695. array(0,0,0,0,0,0,0,1,0),
  696. array(0,0,0,0,0,0,1,1,0),
  697. array(0,0,0,0,0,1,0,1,0),
  698. array(0,0,0,0,1,0,0,1,0),
  699. array(0,0,0,1,0,0,0,1,0),
  700. array(0,0,1,0,0,0,0,1,0),
  701. array(0,1,1,1,1,1,1,1,1),
  702. array(0,0,0,0,0,0,0,1,0),
  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,0,0),
  707. array(0,0,0,0,0,0,0,0,0),
  708. array(0,0,0,0,0,0,0,0,0),
  709. ),
  710. '5' => array(
  711. array(1,1,1,1,1,1,1,1,1),
  712. array(1,0,0,0,0,0,0,0,0),
  713. array(1,0,0,0,0,0,0,0,0),
  714. array(1,0,0,0,0,0,0,0,0),
  715. array(0,1,0,0,0,0,0,0,0),
  716. array(0,0,1,1,1,1,1,0,0),
  717. array(0,0,0,0,0,0,0,1,0),
  718. array(0,0,0,0,0,0,0,0,1),
  719. array(1,0,0,0,0,0,0,0,1),
  720. array(0,1,0,0,0,0,0,1,0),
  721. array(0,0,1,1,1,1,1,0,0),
  722. array(0,0,0,0,0,0,0,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. ),
  726. '6' => array(
  727. array(0,0,1,1,1,1,1,0,0),
  728. array(0,1,0,0,0,0,0,1,0),
  729. array(1,0,0,0,0,0,0,0,1),
  730. array(1,0,0,0,0,0,0,0,0),
  731. array(1,0,0,0,0,0,0,0,0),
  732. array(1,0,0,1,1,1,1,0,0),
  733. array(1,0,1,0,0,0,0,1,0),
  734. array(1,1,0,0,0,0,0,0,1),
  735. array(1,0,0,0,0,0,0,0,1),
  736. array(1,0,0,0,0,0,0,0,1),
  737. array(0,1,0,0,0,0,0,1,0),
  738. array(0,0,1,1,1,1,1,0,0),
  739. array(0,0,0,0,0,0,0,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. ),
  743. '7' => array(
  744. array(1,1,1,1,1,1,1,1,1),
  745. array(1,0,0,0,0,0,0,0,1),
  746. array(0,0,0,0,0,0,0,1,0),
  747. array(0,0,0,0,0,0,1,0,0),
  748. array(0,0,0,0,0,1,0,0,0),
  749. array(0,0,0,0,1,0,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,0,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. ),
  759. '8' => array(
  760. array(0,0,1,1,1,1,1,0,0),
  761. array(0,1,0,0,0,0,0,1,0),
  762. array(1,0,0,0,0,0,0,0,1),
  763. array(1,0,0,0,0,0,0,0,1),
  764. array(1,0,0,0,0,0,0,0,1),
  765. array(0,1,0,0,0,0,0,1,0),
  766. array(0,0,1,1,1,1,1,0,0),
  767. array(0,1,0,0,0,0,0,1,0),
  768. array(1,0,0,0,0,0,0,0,1),
  769. array(1,0,0,0,0,0,0,0,1),
  770. array(1,0,0,0,0,0,0,0,1),
  771. array(0,1,0,0,0,0,0,1,0),
  772. array(0,0,1,1,1,1,1,0,0),
  773. array(0,0,0,0,0,0,0,0,0),
  774. ),
  775. '9' => array(
  776. array(0,0,0,1,1,1,1,0,0),
  777. array(0,0,1,0,0,0,0,1,0),
  778. array(0,1,0,0,0,0,0,0,1),
  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,1,1),
  782. array(0,0,1,1,1,1,1,0,1),
  783. array(0,0,0,0,0,0,0,0,1),
  784. array(0,0,0,0,0,0,0,0,1),
  785. array(0,1,0,0,0,0,0,0,1),
  786. array(0,0,1,0,0,0,0,1,0),
  787. array(0,0,0,1,1,1,1,0,0),
  788. array(0,0,0,0,0,0,0,0,0),
  789. array(0,0,0,0,0,0,0,0,0),
  790. ),
  791. )
  792. );
  793. }
  794. }