Base64EncoderTest.php 6.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. <?php
  2. require_once 'Swift/Encoder/Base64Encoder.php';
  3. class Swift_Encoder_Base64EncoderTest extends UnitTestCase
  4. {
  5. private $_encoder;
  6. public function setUp()
  7. {
  8. $this->_encoder = new Swift_Encoder_Base64Encoder();
  9. }
  10. /*
  11. There's really no point in testing the entire base64 encoding to the
  12. level QP encoding has been tested. base64_encode() has been in PHP for
  13. years.
  14. */
  15. public function testInputOutputRatioIs3to4Bytes()
  16. {
  17. /*
  18. RFC 2045, 6.8
  19. The encoding process represents 24-bit groups of input bits as output
  20. strings of 4 encoded characters. Proceeding from left to right, a
  21. 24-bit input group is formed by concatenating 3 8bit input groups.
  22. These 24 bits are then treated as 4 concatenated 6-bit groups, each
  23. of which is translated into a single digit in the base64 alphabet.
  24. */
  25. $this->assertEqual(
  26. 'MTIz', $this->_encoder->encodeString('123'),
  27. '%s: 3 bytes of input should yield 4 bytes of output'
  28. );
  29. $this->assertEqual(
  30. 'MTIzNDU2', $this->_encoder->encodeString('123456'),
  31. '%s: 6 bytes in input should yield 8 bytes of output'
  32. );
  33. $this->assertEqual(
  34. 'MTIzNDU2Nzg5', $this->_encoder->encodeString('123456789'),
  35. '%s: 9 bytes in input should yield 12 bytes of output'
  36. );
  37. }
  38. public function testPadLength()
  39. {
  40. /*
  41. RFC 2045, 6.8
  42. Special processing is performed if fewer than 24 bits are available
  43. at the end of the data being encoded. A full encoding quantum is
  44. always completed at the end of a body. When fewer than 24 input bits
  45. are available in an input group, zero bits are added (on the right)
  46. to form an integral number of 6-bit groups. Padding at the end of
  47. the data is performed using the "=" character. Since all base64
  48. input is an integral number of octets, only the following cases can
  49. arise: (1) the final quantum of encoding input is an integral
  50. multiple of 24 bits; here, the final unit of encoded output will be
  51. an integral multiple of 4 characters with no "=" padding, (2) the
  52. final quantum of encoding input is exactly 8 bits; here, the final
  53. unit of encoded output will be two characters followed by two "="
  54. padding characters, or (3) the final quantum of encoding input is
  55. exactly 16 bits; here, the final unit of encoded output will be three
  56. characters followed by one "=" padding character.
  57. */
  58. for ($i = 0; $i < 30; ++$i)
  59. {
  60. $input = pack('C', rand(0, 255));
  61. $this->assertPattern(
  62. '~^[a-zA-Z0-9/\+]{2}==$~', $this->_encoder->encodeString($input),
  63. '%s: A single byte should have 2 bytes of padding'
  64. );
  65. }
  66. for ($i = 0; $i < 30; ++$i)
  67. {
  68. $input = pack('C*', rand(0, 255), rand(0, 255));
  69. $this->assertPattern(
  70. '~^[a-zA-Z0-9/\+]{3}=$~', $this->_encoder->encodeString($input),
  71. '%s: Two bytes should have 1 byte of padding'
  72. );
  73. }
  74. for ($i = 0; $i < 30; ++$i)
  75. {
  76. $input = pack('C*', rand(0, 255), rand(0, 255), rand(0, 255));
  77. $this->assertPattern(
  78. '~^[a-zA-Z0-9/\+]{4}$~', $this->_encoder->encodeString($input),
  79. '%s: Three bytes should have no padding'
  80. );
  81. }
  82. }
  83. public function testMaximumLineLengthIs76Characters()
  84. {
  85. /*
  86. The encoded output stream must be represented in lines of no more
  87. than 76 characters each. All line breaks or other characters not
  88. found in Table 1 must be ignored by decoding software.
  89. */
  90. $input =
  91. 'abcdefghijklmnopqrstuvwxyz' .
  92. 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' .
  93. '1234567890' .
  94. 'abcdefghijklmnopqrstuvwxyz' .
  95. 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' .
  96. '1234567890' .
  97. 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
  98. $output =
  99. 'YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQk' . //38
  100. 'NERUZHSElKS0xNTk9QUVJTVFVWV1hZWjEyMzQ1' . "\r\n" . //76 *
  101. 'Njc4OTBhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3' . //38
  102. 'h5ekFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFla' . "\r\n" . //76 *
  103. 'MTIzNDU2Nzg5MEFCQ0RFRkdISUpLTE1OT1BRUl' . //38
  104. 'NUVVZXWFla'; //48
  105. $this->assertEqual(
  106. $output, $this->_encoder->encodeString($input),
  107. '%s: Lines should be no more than 76 characters'
  108. );
  109. }
  110. public function testMaximumLineLengthCanBeSpecified()
  111. {
  112. $input =
  113. 'abcdefghijklmnopqrstuvwxyz' .
  114. 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' .
  115. '1234567890' .
  116. 'abcdefghijklmnopqrstuvwxyz' .
  117. 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' .
  118. '1234567890' .
  119. 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
  120. $output =
  121. 'YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQk' . //38
  122. 'NERUZHSElKS0' . "\r\n" . //50 *
  123. 'xNTk9QUVJTVFVWV1hZWjEyMzQ1Njc4OTBhYmNk' . //38
  124. 'ZWZnaGlqa2xt' . "\r\n" . //50 *
  125. 'bm9wcXJzdHV2d3h5ekFCQ0RFRkdISUpLTE1OT1' . //38
  126. 'BRUlNUVVZXWF' . "\r\n" . //50 *
  127. 'laMTIzNDU2Nzg5MEFCQ0RFRkdISUpLTE1OT1BR' . //38
  128. 'UlNUVVZXWFla'; //50 *
  129. $this->assertEqual(
  130. $output, $this->_encoder->encodeString($input, 0, 50),
  131. '%s: Lines should be no more than 100 characters'
  132. );
  133. }
  134. public function testFirstLineLengthCanBeDifferent()
  135. {
  136. $input =
  137. 'abcdefghijklmnopqrstuvwxyz' .
  138. 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' .
  139. '1234567890' .
  140. 'abcdefghijklmnopqrstuvwxyz' .
  141. 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' .
  142. '1234567890' .
  143. 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
  144. $output =
  145. 'YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQk' . //38
  146. 'NERUZHSElKS0xNTk9QU' . "\r\n" . //57 *
  147. 'VJTVFVWV1hZWjEyMzQ1Njc4OTBhYmNkZWZnaGl' . //38
  148. 'qa2xtbm9wcXJzdHV2d3h5ekFCQ0RFRkdISUpLT' . "\r\n" . //76 *
  149. 'E1OT1BRUlNUVVZXWFlaMTIzNDU2Nzg5MEFCQ0R' . //38
  150. 'FRkdISUpLTE1OT1BRUlNUVVZXWFla'; //67
  151. $this->assertEqual(
  152. $output, $this->_encoder->encodeString($input, 19),
  153. '%s: First line offset is 19 so first line should be 57 chars long'
  154. );
  155. }
  156. }