<?php
/*
Bubble Babble Binary Data Encoding - PHP5 Library
See http://b...content-available-to-author-only...z.net/archives/web/Bubble_Babble.html for details.
Copyright 2011 BohwaZ - http://b...content-available-to-author-only...z.net/
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://w...content-available-to-author-only...u.org/licenses/>.
Based on :
- Bubble Babble spec: http://w...content-available-to-author-only...k.net/589/Bubble_Babble_Encoding.txt
- Nitrxgen PHP script: http://w...content-available-to-author-only...n.net/bubblebabble.php
- Bubble Babble encoder for Go: http://c...content-available-to-author-only...t.com/181122
Use:
$encoded = BubbleBabble::Encode('Pineapple');
// => xigak-nyryk-humil-bosek-sonax
$decoded = BubbleBabble::Decode('xigak-nyryk-humil-bosek-sonax');
// => Pineapple
If your prefer procedural code, just use:
function babble_encode($str)
{
return BubbleBabble::Encode($str);
}
function babble_decode($str)
{
return BubbleBabble::Decode($str);
}
*/
class BubbleBabble_Exception extends Exception
{
}
class BubbleBabble
{
// The table of Babble vowels
static protected $vowels = 'aeiouy';
// The table of Babble consonants.
static protected $consonants = 'bcdfghklmnprstvzx';
// Encodes $src in a babble string
static public function Encode($src)
{
$src = (string) $src; // Just to make sure PHP doesn't casts $a = '123456789'; as an int
$out = 'x';
$c = 1; // checksum
for ($i = 0;; $i += 2)
{
{
$out .= self::$vowels[$c%6] . self::$consonants[16] . self::$vowels[$c/6];
break;
}
$out .= self::$vowels[((($byte1>>6)&3)+$c)%6];
$out .= self::$consonants[($byte1>>2)&15];
$out .= self::$vowels[(($byte1&3)+($c/6))%6];
break;
$byte2 = ord($src[$i + 1]); $out .= self::$consonants[($byte2>>4)&15];
$out .= '-';
$out .= self::$consonants[$byte2&15];
$c = ($c * 5 + $byte1 * 7 + $byte2) % 36;
}
$out .= 'x';
return $out;
}
static protected function _decode2WayByte($a1, $a2, $offset)
{
if ($a1 > 16)
throw new BubbleBabble_Exception("Corrupt string at offset ".$offset);
if ($a2 > 16)
throw new BubbleBabble_Exception("Corrupt string at offset ".($offset+2));
return ($a1 << 4) | $a2;
}
static protected function _decode3WayByte($a1, $a2, $a3, $offset, $c)
{
$high2 = ($a1 - ($c%6) + 6) % 6;
if ($high2 >= 4)
throw new BubbleBabble_Exception("Corrupt string at offset ".$offset);
if ($a2 > 16)
throw new BubbleBabble_Exception("Corrupt string at offset ".($offset+1));
$mid4 = $a2;
$low2 = ($a3 - ($c/6%6) + 6) % 6;
if ($low2 >= 4)
throw new BubbleBabble_Exception("Corrupt string at offset ".($offset+2));
return $high2<<6 | $mid4<<2 | $low2;
}
protected static function _decodeTuple($src, $pos)
{
strpos(self::$vowels, $src[0]), strpos(self::$consonants, $src[1]), strpos(self::$vowels, $src[2]) );
{
$tuple[] = strpos(self::$consonants, $src[3]); $tuple[] = '-';
$tuple[] = strpos(self::$consonants, $src[5]); }
return $tuple;
}
public static function Decode($src)
{
$src = (string) $src;
$c = 1; // checksum
// Integrity checks
if ($src[0] != 'x')
throw new BubbleBabble_Exception("Corrupt string at offset 0: must begin with a 'x'");
throw new BubbleBabble_Exception("Corrupt string at offset 0: must end with a 'x'");
throw new BubbleBabble_Exception("Corrupt string at offset 0: wrong length");
$last_tuple = count($src) - 1; $out = '';
foreach ($src as $k=>$tuple)
{
$pos = $k * 6;
$tuple = self::_decodeTuple($tuple, $pos);
if ($k == $last_tuple)
{
if ($tuple[1] == 16)
{
if ($tuple[0] != $c % 6)
throw new BubbleBabble_Exception("Corrupt string at offset $pos (checksum)");
if ($tuple[2] != (int)($c / 6))
throw new BubbleBabble_Exception("Corrupt string at offset ".($pos+2)." (checksum)");
}
else
{
$byte = self::_decode3WayByte($tuple[0], $tuple[1], $tuple[2], $pos, $c);
}
}
else
{
$byte1 = self::_decode3WayByte($tuple[0], $tuple[1], $tuple[2], $pos, $c);
$byte2 = self::_decode2WayByte($tuple[3], $tuple[5], $pos);
$c = ($c * 5 + $byte1 * 7 + $byte2) % 36;
}
}
return $out;
}
// Returns true if $string seems to be a BubbleBabble encoded string
static public function Detect($string)
{
if ($string[0] != 'x' || substr($string, -1) != 'x') return false;
return false;
if (!preg_match('/^(['.self::$consonants.self::$vowels.']{5})(-(?1))*$/', $string)) return false;
return true;
}
}
?>