EncoderTest.php 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487
  1. <?php
  2. declare(strict_types = 1);
  3. namespace BaconQrCodeTest\Encoder;
  4. use BaconQrCode\Common\BitArray;
  5. use BaconQrCode\Common\ErrorCorrectionLevel;
  6. use BaconQrCode\Common\Mode;
  7. use BaconQrCode\Common\Version;
  8. use BaconQrCode\Encoder\Encoder;
  9. use BaconQrCode\Exception\WriterException;
  10. use PHPUnit\Framework\TestCase;
  11. use ReflectionClass;
  12. use ReflectionMethod;
  13. use SplFixedArray;
  14. final class EncoderTest extends TestCase
  15. {
  16. /**
  17. * @var ReflectionMethod[]
  18. */
  19. protected $methods = [];
  20. public function setUp() : void
  21. {
  22. // Hack to be able to test protected methods
  23. $reflection = new ReflectionClass(Encoder::class);
  24. foreach ($reflection->getMethods(ReflectionMethod::IS_STATIC) as $method) {
  25. $method->setAccessible(true);
  26. $this->methods[$method->getName()] = $method;
  27. }
  28. }
  29. public function testGetAlphanumericCode() : void
  30. {
  31. // The first ten code points are numbers.
  32. for ($i = 0; $i < 10; ++$i) {
  33. $this->assertSame($i, $this->methods['getAlphanumericCode']->invoke(null, ord('0') + $i));
  34. }
  35. // The next 26 code points are capital alphabet letters.
  36. for ($i = 10; $i < 36; ++$i) {
  37. // The first ten code points are numbers
  38. $this->assertSame($i, $this->methods['getAlphanumericCode']->invoke(null, ord('A') + $i - 10));
  39. }
  40. // Others are symbol letters.
  41. $this->assertSame(36, $this->methods['getAlphanumericCode']->invoke(null, ord(' ')));
  42. $this->assertSame(37, $this->methods['getAlphanumericCode']->invoke(null, ord('$')));
  43. $this->assertSame(38, $this->methods['getAlphanumericCode']->invoke(null, ord('%')));
  44. $this->assertSame(39, $this->methods['getAlphanumericCode']->invoke(null, ord('*')));
  45. $this->assertSame(40, $this->methods['getAlphanumericCode']->invoke(null, ord('+')));
  46. $this->assertSame(41, $this->methods['getAlphanumericCode']->invoke(null, ord('-')));
  47. $this->assertSame(42, $this->methods['getAlphanumericCode']->invoke(null, ord('.')));
  48. $this->assertSame(43, $this->methods['getAlphanumericCode']->invoke(null, ord('/')));
  49. $this->assertSame(44, $this->methods['getAlphanumericCode']->invoke(null, ord(':')));
  50. // Should return -1 for other letters.
  51. $this->assertSame(-1, $this->methods['getAlphanumericCode']->invoke(null, ord('a')));
  52. $this->assertSame(-1, $this->methods['getAlphanumericCode']->invoke(null, ord('#')));
  53. $this->assertSame(-1, $this->methods['getAlphanumericCode']->invoke(null, ord("\0")));
  54. }
  55. public function testChooseMode() : void
  56. {
  57. // Numeric mode
  58. $this->assertSame(Mode::NUMERIC(), $this->methods['chooseMode']->invoke(null, '0'));
  59. $this->assertSame(Mode::NUMERIC(), $this->methods['chooseMode']->invoke(null, '0123456789'));
  60. // Alphanumeric mode
  61. $this->assertSame(Mode::ALPHANUMERIC(), $this->methods['chooseMode']->invoke(null, 'A'));
  62. $this->assertSame(
  63. Mode::ALPHANUMERIC(),
  64. $this->methods['chooseMode']->invoke(null, '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:')
  65. );
  66. // 8-bit byte mode
  67. $this->assertSame(Mode::BYTE(), $this->methods['chooseMode']->invoke(null, 'a'));
  68. $this->assertSame(Mode::BYTE(), $this->methods['chooseMode']->invoke(null, '#'));
  69. $this->assertSame(Mode::BYTE(), $this->methods['chooseMode']->invoke(null, ''));
  70. // AIUE in Hiragana in SHIFT-JIS
  71. $this->assertSame(Mode::BYTE(), $this->methods['chooseMode']->invoke(null, "\x8\xa\x8\xa\x8\xa\x8\xa6"));
  72. // Nihon in Kanji in SHIFT-JIS
  73. $this->assertSame(Mode::BYTE(), $this->methods['chooseMode']->invoke(null, "\x9\xf\x9\x7b"));
  74. // Sou-Utso-Byou in Kanji in SHIFT-JIS
  75. $this->assertSame(Mode::BYTE(), $this->methods['chooseMode']->invoke(null, "\xe\x4\x9\x5\x9\x61"));
  76. }
  77. public function testEncode() : void
  78. {
  79. $qrCode = Encoder::encode('ABCDEF', ErrorCorrectionLevel::H());
  80. $expected = "<<\n"
  81. . " mode: ALPHANUMERIC\n"
  82. . " ecLevel: H\n"
  83. . " version: 1\n"
  84. . " maskPattern: 0\n"
  85. . " matrix:\n"
  86. . " 1 1 1 1 1 1 1 0 1 1 1 1 0 0 1 1 1 1 1 1 1\n"
  87. . " 1 0 0 0 0 0 1 0 0 1 1 1 0 0 1 0 0 0 0 0 1\n"
  88. . " 1 0 1 1 1 0 1 0 0 1 0 1 1 0 1 0 1 1 1 0 1\n"
  89. . " 1 0 1 1 1 0 1 0 1 1 1 0 1 0 1 0 1 1 1 0 1\n"
  90. . " 1 0 1 1 1 0 1 0 0 1 1 1 0 0 1 0 1 1 1 0 1\n"
  91. . " 1 0 0 0 0 0 1 0 0 1 0 0 0 0 1 0 0 0 0 0 1\n"
  92. . " 1 1 1 1 1 1 1 0 1 0 1 0 1 0 1 1 1 1 1 1 1\n"
  93. . " 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0\n"
  94. . " 0 0 1 0 1 1 1 0 1 1 0 0 1 1 0 0 0 1 0 0 1\n"
  95. . " 1 0 1 1 1 0 0 1 0 0 0 1 0 1 0 0 0 0 0 0 0\n"
  96. . " 0 0 1 1 0 0 1 0 1 0 0 0 1 0 1 0 1 0 1 1 0\n"
  97. . " 1 1 0 1 0 1 0 1 1 1 0 1 0 1 0 0 0 0 0 1 0\n"
  98. . " 0 0 1 1 0 1 1 1 1 0 0 0 1 0 1 0 1 1 1 1 0\n"
  99. . " 0 0 0 0 0 0 0 0 1 0 0 1 1 1 0 1 0 1 0 0 0\n"
  100. . " 1 1 1 1 1 1 1 0 0 0 1 0 1 0 1 1 0 0 0 0 1\n"
  101. . " 1 0 0 0 0 0 1 0 1 1 1 1 0 1 0 1 1 1 1 0 1\n"
  102. . " 1 0 1 1 1 0 1 0 1 0 1 1 0 1 0 1 0 0 0 0 1\n"
  103. . " 1 0 1 1 1 0 1 0 0 1 1 0 1 1 1 1 0 1 0 1 0\n"
  104. . " 1 0 1 1 1 0 1 0 1 0 0 0 1 0 1 0 1 1 1 0 1\n"
  105. . " 1 0 0 0 0 0 1 0 0 1 1 0 1 1 0 1 0 0 0 1 1\n"
  106. . " 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 1 0 1 0 1\n"
  107. . ">>\n";
  108. $this->assertSame($expected, (string) $qrCode);
  109. }
  110. public function testSimpleUtf8Eci() : void
  111. {
  112. $qrCode = Encoder::encode('hello', ErrorCorrectionLevel::H(), 'utf-8');
  113. $expected = "<<\n"
  114. . " mode: BYTE\n"
  115. . " ecLevel: H\n"
  116. . " version: 1\n"
  117. . " maskPattern: 3\n"
  118. . " matrix:\n"
  119. . " 1 1 1 1 1 1 1 0 0 0 0 0 0 0 1 1 1 1 1 1 1\n"
  120. . " 1 0 0 0 0 0 1 0 0 0 1 0 1 0 1 0 0 0 0 0 1\n"
  121. . " 1 0 1 1 1 0 1 0 0 1 0 1 0 0 1 0 1 1 1 0 1\n"
  122. . " 1 0 1 1 1 0 1 0 0 1 1 0 1 0 1 0 1 1 1 0 1\n"
  123. . " 1 0 1 1 1 0 1 0 1 0 1 0 1 0 1 0 1 1 1 0 1\n"
  124. . " 1 0 0 0 0 0 1 0 0 0 0 0 1 0 1 0 0 0 0 0 1\n"
  125. . " 1 1 1 1 1 1 1 0 1 0 1 0 1 0 1 1 1 1 1 1 1\n"
  126. . " 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0\n"
  127. . " 0 0 1 1 0 0 1 1 1 1 0 0 0 1 1 0 1 0 0 0 0\n"
  128. . " 0 0 1 1 1 0 0 0 0 0 1 1 0 0 0 1 0 1 1 1 0\n"
  129. . " 0 1 0 1 0 1 1 1 0 1 0 1 0 0 0 0 0 1 1 1 1\n"
  130. . " 1 1 0 0 1 0 0 1 1 0 0 1 1 1 1 0 1 0 1 1 0\n"
  131. . " 0 0 0 0 1 0 1 1 1 1 0 0 0 0 0 1 0 0 1 0 0\n"
  132. . " 0 0 0 0 0 0 0 0 1 1 1 1 0 0 1 1 1 0 0 0 1\n"
  133. . " 1 1 1 1 1 1 1 0 1 1 1 0 1 0 1 1 0 0 1 0 0\n"
  134. . " 1 0 0 0 0 0 1 0 0 0 1 0 0 1 1 1 1 1 1 0 1\n"
  135. . " 1 0 1 1 1 0 1 0 0 1 0 0 0 0 1 1 0 0 0 0 0\n"
  136. . " 1 0 1 1 1 0 1 0 1 1 1 0 1 0 0 0 1 1 0 0 0\n"
  137. . " 1 0 1 1 1 0 1 0 1 1 0 0 0 1 0 0 1 0 0 0 0\n"
  138. . " 1 0 0 0 0 0 1 0 0 0 0 1 1 0 1 0 1 0 1 1 0\n"
  139. . " 1 1 1 1 1 1 1 0 0 1 0 1 1 1 0 1 1 0 0 0 0\n"
  140. . ">>\n";
  141. $this->assertSame($expected, (string) $qrCode);
  142. }
  143. public function testAppendModeInfo() : void
  144. {
  145. $bits = new BitArray();
  146. $this->methods['appendModeInfo']->invoke(null, Mode::NUMERIC(), $bits);
  147. $this->assertSame(' ...X', (string) $bits);
  148. }
  149. public function testAppendLengthInfo() : void
  150. {
  151. // 1 letter (1/1), 10 bits.
  152. $bits = new BitArray();
  153. $this->methods['appendLengthInfo']->invoke(
  154. null,
  155. 1,
  156. Version::getVersionForNumber(1),
  157. Mode::NUMERIC(),
  158. $bits
  159. );
  160. $this->assertSame(' ........ .X', (string) $bits);
  161. // 2 letters (2/1), 11 bits.
  162. $bits = new BitArray();
  163. $this->methods['appendLengthInfo']->invoke(
  164. null,
  165. 2,
  166. Version::getVersionForNumber(10),
  167. Mode::ALPHANUMERIC(),
  168. $bits
  169. );
  170. $this->assertSame(' ........ .X.', (string) $bits);
  171. // 255 letters (255/1), 16 bits.
  172. $bits = new BitArray();
  173. $this->methods['appendLengthInfo']->invoke(
  174. null,
  175. 255,
  176. Version::getVersionForNumber(27),
  177. Mode::BYTE(),
  178. $bits
  179. );
  180. $this->assertSame(' ........ XXXXXXXX', (string) $bits);
  181. // 512 letters (1024/2), 12 bits.
  182. $bits = new BitArray();
  183. $this->methods['appendLengthInfo']->invoke(
  184. null,
  185. 512,
  186. Version::getVersionForNumber(40),
  187. Mode::KANJI(),
  188. $bits
  189. );
  190. $this->assertSame(' ..X..... ....', (string) $bits);
  191. }
  192. public function testAppendBytes() : void
  193. {
  194. // Should use appendNumericBytes.
  195. // 1 = 01 = 0001 in 4 bits.
  196. $bits = new BitArray();
  197. $this->methods['appendBytes']->invoke(
  198. null,
  199. '1',
  200. Mode::NUMERIC(),
  201. $bits,
  202. Encoder::DEFAULT_BYTE_MODE_ECODING
  203. );
  204. $this->assertSame(' ...X', (string) $bits);
  205. // Should use appendAlphaNumericBytes.
  206. // A = 10 = 0xa = 001010 in 6 bits.
  207. $bits = new BitArray();
  208. $this->methods['appendBytes']->invoke(
  209. null,
  210. 'A',
  211. Mode::ALPHANUMERIC(),
  212. $bits,
  213. Encoder::DEFAULT_BYTE_MODE_ECODING
  214. );
  215. $this->assertSame(' ..X.X.', (string) $bits);
  216. // Should use append8BitBytes.
  217. // 0x61, 0x62, 0x63
  218. $bits = new BitArray();
  219. $this->methods['appendBytes']->invoke(
  220. null,
  221. 'abc',
  222. Mode::BYTE(),
  223. $bits,
  224. Encoder::DEFAULT_BYTE_MODE_ECODING
  225. );
  226. $this->assertSame(' .XX....X .XX...X. .XX...XX', (string) $bits);
  227. // Should use appendKanjiBytes.
  228. // 0x93, 0x5f
  229. $bits = new BitArray();
  230. $this->methods['appendBytes']->invoke(
  231. null,
  232. "\x93\x5f",
  233. Mode::KANJI(),
  234. $bits,
  235. Encoder::DEFAULT_BYTE_MODE_ECODING
  236. );
  237. $this->assertSame(' .XX.XX.. XXXXX', (string) $bits);
  238. // Lower letters such as 'a' cannot be encoded in alphanumeric mode.
  239. $this->expectException(WriterException::class);
  240. $this->methods['appendBytes']->invoke(
  241. null,
  242. 'a',
  243. Mode::ALPHANUMERIC(),
  244. $bits,
  245. Encoder::DEFAULT_BYTE_MODE_ECODING
  246. );
  247. }
  248. public function testTerminateBits() : void
  249. {
  250. $bits = new BitArray();
  251. $this->methods['terminateBits']->invoke(null, 0, $bits);
  252. $this->assertSame('', (string) $bits);
  253. $bits = new BitArray();
  254. $this->methods['terminateBits']->invoke(null, 1, $bits);
  255. $this->assertSame(' ........', (string) $bits);
  256. $bits = new BitArray();
  257. $bits->appendBits(0, 3);
  258. $this->methods['terminateBits']->invoke(null, 1, $bits);
  259. $this->assertSame(' ........', (string) $bits);
  260. $bits = new BitArray();
  261. $bits->appendBits(0, 5);
  262. $this->methods['terminateBits']->invoke(null, 1, $bits);
  263. $this->assertSame(' ........', (string) $bits);
  264. $bits = new BitArray();
  265. $bits->appendBits(0, 8);
  266. $this->methods['terminateBits']->invoke(null, 1, $bits);
  267. $this->assertSame(' ........', (string) $bits);
  268. $bits = new BitArray();
  269. $this->methods['terminateBits']->invoke(null, 2, $bits);
  270. $this->assertSame(' ........ XXX.XX..', (string) $bits);
  271. $bits = new BitArray();
  272. $bits->appendBits(0, 1);
  273. $this->methods['terminateBits']->invoke(null, 3, $bits);
  274. $this->assertSame(' ........ XXX.XX.. ...X...X', (string) $bits);
  275. }
  276. public function testGetNumDataBytesAndNumEcBytesForBlockId() : void
  277. {
  278. // Version 1-H.
  279. list($numDataBytes, $numEcBytes) = $this->methods['getNumDataBytesAndNumEcBytesForBlockId']
  280. ->invoke(null, 26, 9, 1, 0);
  281. $this->assertSame(9, $numDataBytes);
  282. $this->assertSame(17, $numEcBytes);
  283. // Version 3-H. 2 blocks.
  284. list($numDataBytes, $numEcBytes) = $this->methods['getNumDataBytesAndNumEcBytesForBlockId']
  285. ->invoke(null, 70, 26, 2, 0);
  286. $this->assertSame(13, $numDataBytes);
  287. $this->assertSame(22, $numEcBytes);
  288. list($numDataBytes, $numEcBytes) = $this->methods['getNumDataBytesAndNumEcBytesForBlockId']
  289. ->invoke(null, 70, 26, 2, 1);
  290. $this->assertSame(13, $numDataBytes);
  291. $this->assertSame(22, $numEcBytes);
  292. // Version 7-H. (4 + 1) blocks.
  293. list($numDataBytes, $numEcBytes) = $this->methods['getNumDataBytesAndNumEcBytesForBlockId']
  294. ->invoke(null, 196, 66, 5, 0);
  295. $this->assertSame(13, $numDataBytes);
  296. $this->assertSame(26, $numEcBytes);
  297. list($numDataBytes, $numEcBytes) = $this->methods['getNumDataBytesAndNumEcBytesForBlockId']
  298. ->invoke(null, 196, 66, 5, 4);
  299. $this->assertSame(14, $numDataBytes);
  300. $this->assertSame(26, $numEcBytes);
  301. // Version 40-H. (20 + 61) blocks.
  302. list($numDataBytes, $numEcBytes) = $this->methods['getNumDataBytesAndNumEcBytesForBlockId']
  303. ->invoke(null, 3706, 1276, 81, 0);
  304. $this->assertSame(15, $numDataBytes);
  305. $this->assertSame(30, $numEcBytes);
  306. list($numDataBytes, $numEcBytes) = $this->methods['getNumDataBytesAndNumEcBytesForBlockId']
  307. ->invoke(null, 3706, 1276, 81, 20);
  308. $this->assertSame(16, $numDataBytes);
  309. $this->assertSame(30, $numEcBytes);
  310. list($numDataBytes, $numEcBytes) = $this->methods['getNumDataBytesAndNumEcBytesForBlockId']
  311. ->invoke(null, 3706, 1276, 81, 80);
  312. $this->assertSame(16, $numDataBytes);
  313. $this->assertSame(30, $numEcBytes);
  314. }
  315. public function testInterleaveWithEcBytes() : void
  316. {
  317. $dataBytes = SplFixedArray::fromArray([32, 65, 205, 69, 41, 220, 46, 128, 236], false);
  318. $in = new BitArray();
  319. foreach ($dataBytes as $dataByte) {
  320. $in->appendBits($dataByte, 8);
  321. }
  322. $outBits = $this->methods['interleaveWithEcBytes']->invoke(null, $in, 26, 9, 1);
  323. $expected = SplFixedArray::fromArray([
  324. // Data bytes.
  325. 32, 65, 205, 69, 41, 220, 46, 128, 236,
  326. // Error correction bytes.
  327. 42, 159, 74, 221, 244, 169, 239, 150, 138, 70, 237, 85, 224, 96, 74, 219, 61,
  328. ], false);
  329. $out = $outBits->toBytes(0, count($expected));
  330. $this->assertEquals($expected, $out);
  331. }
  332. public function testAppendNumericBytes() : void
  333. {
  334. // 1 = 01 = 0001 in 4 bits.
  335. $bits = new BitArray();
  336. $this->methods['appendNumericBytes']->invoke(null, '1', $bits);
  337. $this->assertSame(' ...X', (string) $bits);
  338. // 12 = 0xc = 0001100 in 7 bits.
  339. $bits = new BitArray();
  340. $this->methods['appendNumericBytes']->invoke(null, '12', $bits);
  341. $this->assertSame(' ...XX..', (string) $bits);
  342. // 123 = 0x7b = 0001111011 in 10 bits.
  343. $bits = new BitArray();
  344. $this->methods['appendNumericBytes']->invoke(null, '123', $bits);
  345. $this->assertSame(' ...XXXX. XX', (string) $bits);
  346. // 1234 = "123" + "4" = 0001111011 + 0100 in 14 bits.
  347. $bits = new BitArray();
  348. $this->methods['appendNumericBytes']->invoke(null, '1234', $bits);
  349. $this->assertSame(' ...XXXX. XX.X..', (string) $bits);
  350. // Empty
  351. $bits = new BitArray();
  352. $this->methods['appendNumericBytes']->invoke(null, '', $bits);
  353. $this->assertSame('', (string) $bits);
  354. }
  355. public function testAppendAlphanumericBytes() : void
  356. {
  357. $bits = new BitArray();
  358. $this->methods['appendAlphanumericBytes']->invoke(null, 'A', $bits);
  359. $this->assertSame(' ..X.X.', (string) $bits);
  360. $bits = new BitArray();
  361. $this->methods['appendAlphanumericBytes']->invoke(null, 'AB', $bits);
  362. $this->assertSame(' ..XXX..X X.X', (string) $bits);
  363. $bits = new BitArray();
  364. $this->methods['appendAlphanumericBytes']->invoke(null, 'ABC', $bits);
  365. $this->assertSame(' ..XXX..X X.X..XX. .', (string) $bits);
  366. // Empty
  367. $bits = new BitArray();
  368. $this->methods['appendAlphanumericBytes']->invoke(null, '', $bits);
  369. $this->assertSame('', (string) $bits);
  370. // Invalid data
  371. $this->expectException(WriterException::class);
  372. $bits = new BitArray();
  373. $this->methods['appendAlphanumericBytes']->invoke(null, 'abc', $bits);
  374. }
  375. public function testAppend8BitBytes() : void
  376. {
  377. // 0x61, 0x62, 0x63
  378. $bits = new BitArray();
  379. $this->methods['append8BitBytes']->invoke(null, 'abc', $bits, Encoder::DEFAULT_BYTE_MODE_ECODING);
  380. $this->assertSame(' .XX....X .XX...X. .XX...XX', (string) $bits);
  381. // Empty
  382. $bits = new BitArray();
  383. $this->methods['append8BitBytes']->invoke(null, '', $bits, Encoder::DEFAULT_BYTE_MODE_ECODING);
  384. $this->assertSame('', (string) $bits);
  385. }
  386. public function testAppendKanjiBytes() : void
  387. {
  388. // Numbers are from page 21 of JISX0510:2004
  389. $bits = new BitArray();
  390. $this->methods['appendKanjiBytes']->invoke(null, "\x93\x5f", $bits);
  391. $this->assertSame(' .XX.XX.. XXXXX', (string) $bits);
  392. $this->methods['appendKanjiBytes']->invoke(null, "\xe4\xaa", $bits);
  393. $this->assertSame(' .XX.XX.. XXXXXXX. X.X.X.X. X.', (string) $bits);
  394. }
  395. public function testGenerateEcBytes() : void
  396. {
  397. // Numbers are from http://www.swetake.com/qr/qr3.html and
  398. // http://www.swetake.com/qr/qr9.html
  399. $dataBytes = SplFixedArray::fromArray([32, 65, 205, 69, 41, 220, 46, 128, 236], false);
  400. $ecBytes = $this->methods['generateEcBytes']->invoke(null, $dataBytes, 17);
  401. $expected = SplFixedArray::fromArray(
  402. [42, 159, 74, 221, 244, 169, 239, 150, 138, 70, 237, 85, 224, 96, 74, 219, 61],
  403. false
  404. );
  405. $this->assertEquals($expected, $ecBytes);
  406. $dataBytes = SplFixedArray::fromArray(
  407. [67, 70, 22, 38, 54, 70, 86, 102, 118, 134, 150, 166, 182, 198, 214],
  408. false
  409. );
  410. $ecBytes = $this->methods['generateEcBytes']->invoke(null, $dataBytes, 18);
  411. $expected = SplFixedArray::fromArray(
  412. [175, 80, 155, 64, 178, 45, 214, 233, 65, 209, 12, 155, 117, 31, 140, 214, 27, 187],
  413. false
  414. );
  415. $this->assertEquals($expected, $ecBytes);
  416. // High-order zero coefficient case.
  417. $dataBytes = SplFixedArray::fromArray([32, 49, 205, 69, 42, 20, 0, 236, 17], false);
  418. $ecBytes = $this->methods['generateEcBytes']->invoke(null, $dataBytes, 17);
  419. $expected = SplFixedArray::fromArray(
  420. [0, 3, 130, 179, 194, 0, 55, 211, 110, 79, 98, 72, 170, 96, 211, 137, 213],
  421. false
  422. );
  423. $this->assertEquals($expected, $ecBytes);
  424. }
  425. }