fork download
  1. <?php
  2. /*
  3.   Bubble Babble Binary Data Encoding - PHP5 Library
  4.   See http://b...content-available-to-author-only...z.net/archives/web/Bubble_Babble.html for details.
  5.   Copyright 2011 BohwaZ - http://b...content-available-to-author-only...z.net/
  6.   This program is free software: you can redistribute it and/or modify
  7.   it under the terms of the GNU Lesser General Public License as published by
  8.   the Free Software Foundation, either version 3 of the License, or
  9.   any later version.
  10.   This program is distributed in the hope that it will be useful,
  11.   but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13.   GNU General Public License for more details.
  14.   You should have received a copy of the GNU Lesser General Public License
  15.   along with this program. If not, see <http://w...content-available-to-author-only...u.org/licenses/>.
  16.   Based on :
  17.   - Bubble Babble spec: http://w...content-available-to-author-only...k.net/589/Bubble_Babble_Encoding.txt
  18.   - Nitrxgen PHP script: http://w...content-available-to-author-only...n.net/bubblebabble.php
  19.   - Bubble Babble encoder for Go: http://c...content-available-to-author-only...t.com/181122
  20.   Use:
  21.   $encoded = BubbleBabble::Encode('Pineapple');
  22.   // => xigak-nyryk-humil-bosek-sonax
  23.   $decoded = BubbleBabble::Decode('xigak-nyryk-humil-bosek-sonax');
  24.   // => Pineapple
  25.   If your prefer procedural code, just use:
  26.   function babble_encode($str)
  27.   {
  28.   return BubbleBabble::Encode($str);
  29.   }
  30.   function babble_decode($str)
  31.   {
  32.   return BubbleBabble::Decode($str);
  33.   }
  34. */
  35. class BubbleBabble_Exception extends Exception
  36. {
  37. }
  38. class BubbleBabble
  39. {
  40. // The table of Babble vowels
  41. static protected $vowels = 'aeiouy';
  42. // The table of Babble consonants.
  43. static protected $consonants = 'bcdfghklmnprstvzx';
  44. // Encodes $src in a babble string
  45. static public function Encode($src)
  46. {
  47. $src = (string) $src; // Just to make sure PHP doesn't casts $a = '123456789'; as an int
  48. $out = 'x';
  49. $c = 1; // checksum
  50. for ($i = 0;; $i += 2)
  51. {
  52. if ($i >= strlen($src))
  53. {
  54. $out .= self::$vowels[$c%6] . self::$consonants[16] . self::$vowels[$c/6];
  55. break;
  56. }
  57. $byte1 = ord($src[$i]);
  58. $out .= self::$vowels[((($byte1>>6)&3)+$c)%6];
  59. $out .= self::$consonants[($byte1>>2)&15];
  60. $out .= self::$vowels[(($byte1&3)+($c/6))%6];
  61. if ($i+1 >= strlen($src))
  62. break;
  63. $byte2 = ord($src[$i + 1]);
  64. $out .= self::$consonants[($byte2>>4)&15];
  65. $out .= '-';
  66. $out .= self::$consonants[$byte2&15];
  67. $c = ($c * 5 + $byte1 * 7 + $byte2) % 36;
  68. }
  69. $out .= 'x';
  70. return $out;
  71. }
  72. static protected function _decode2WayByte($a1, $a2, $offset)
  73. {
  74. if ($a1 > 16)
  75. throw new BubbleBabble_Exception("Corrupt string at offset ".$offset);
  76. if ($a2 > 16)
  77. throw new BubbleBabble_Exception("Corrupt string at offset ".($offset+2));
  78. return ($a1 << 4) | $a2;
  79. }
  80. static protected function _decode3WayByte($a1, $a2, $a3, $offset, $c)
  81. {
  82. $high2 = ($a1 - ($c%6) + 6) % 6;
  83. if ($high2 >= 4)
  84. throw new BubbleBabble_Exception("Corrupt string at offset ".$offset);
  85. if ($a2 > 16)
  86. throw new BubbleBabble_Exception("Corrupt string at offset ".($offset+1));
  87. $mid4 = $a2;
  88. $low2 = ($a3 - ($c/6%6) + 6) % 6;
  89. if ($low2 >= 4)
  90. throw new BubbleBabble_Exception("Corrupt string at offset ".($offset+2));
  91. return $high2<<6 | $mid4<<2 | $low2;
  92. }
  93. protected static function _decodeTuple($src, $pos)
  94. {
  95. $tuple = array(
  96. strpos(self::$vowels, $src[0]),
  97. strpos(self::$consonants, $src[1]),
  98. strpos(self::$vowels, $src[2])
  99. );
  100. if (isset($src[3]))
  101. {
  102. $tuple[] = strpos(self::$consonants, $src[3]);
  103. $tuple[] = '-';
  104. $tuple[] = strpos(self::$consonants, $src[5]);
  105. }
  106. return $tuple;
  107. }
  108. public static function Decode($src)
  109. {
  110. $src = (string) $src;
  111. $c = 1; // checksum
  112. // Integrity checks
  113. if ($src[0] != 'x')
  114. throw new BubbleBabble_Exception("Corrupt string at offset 0: must begin with a 'x'");
  115. if (substr($src, -1) != 'x')
  116. throw new BubbleBabble_Exception("Corrupt string at offset 0: must end with a 'x'");
  117. if (strlen($src) != 5 && strlen($src)%6 != 5)
  118. throw new BubbleBabble_Exception("Corrupt string at offset 0: wrong length");
  119. $src = str_split(substr($src, 1, -1), 6);
  120. $last_tuple = count($src) - 1;
  121. $out = '';
  122. foreach ($src as $k=>$tuple)
  123. {
  124. $pos = $k * 6;
  125. $tuple = self::_decodeTuple($tuple, $pos);
  126. if ($k == $last_tuple)
  127. {
  128. if ($tuple[1] == 16)
  129. {
  130. if ($tuple[0] != $c % 6)
  131. throw new BubbleBabble_Exception("Corrupt string at offset $pos (checksum)");
  132. if ($tuple[2] != (int)($c / 6))
  133. throw new BubbleBabble_Exception("Corrupt string at offset ".($pos+2)." (checksum)");
  134. }
  135. else
  136. {
  137. $byte = self::_decode3WayByte($tuple[0], $tuple[1], $tuple[2], $pos, $c);
  138. $out .= chr($byte);
  139. }
  140. }
  141. else
  142. {
  143. $byte1 = self::_decode3WayByte($tuple[0], $tuple[1], $tuple[2], $pos, $c);
  144. $byte2 = self::_decode2WayByte($tuple[3], $tuple[5], $pos);
  145. $out .= chr($byte1);
  146. $out .= chr($byte2);
  147. $c = ($c * 5 + $byte1 * 7 + $byte2) % 36;
  148. }
  149. }
  150. return $out;
  151. }
  152. // Returns true if $string seems to be a BubbleBabble encoded string
  153. static public function Detect($string)
  154. {
  155. if ($string[0] != 'x' || substr($string, -1) != 'x')
  156. return false;
  157. if (strlen($string) != 5 && strlen($string)%6 != 5)
  158. return false;
  159. if (!preg_match('/^(['.self::$consonants.self::$vowels.']{5})(-(?1))*$/', $string))
  160. return false;
  161. return true;
  162. }
  163. }
  164. ?>
Success #stdin #stdout 0.01s 52488KB
stdin
Standard input is empty
stdout
Standard output is empty