// Размер id в битах
define('BITS_PER_ID', 16);
// Разделитель
define('BITS_PREFIX', '1010101010101011');
// массив заменяемых букв
// ключами массива являются русские буквы
// английские в качестве значений
$replace = array('а'=>'a', 'о'=>'o', 'е'=>'e', 'с'=>'c', 'р'=>'p', 'х'=>'x', 'у'=>'y');
function encode($text, $replace, $id)
{
// Переводим id в двоичную сиcтему и добавляем разделитель
$mask = BITS_PREFIX.sprintf('%0'.BITS_PER_ID.'b', $id);
$rus = implode(array_keys($replace));
$regex = "~[$rus](?:(?=[а-яё])|(?<=[а-яё].)(?<=[^$rus].))~u";
return preg_replace_callback(
$regex, function ($m) use ($replace, $mask) {
static $i = 0;
strlen($mask) > $i || $i = 0;
return $mask[$i++] ? $replace[$m[0]] : $m[0];
}, $text
);
}
function decode($text, $replace)
{
$rus = implode(array_keys($replace));
$eng = implode(array_values($replace));
$regex = "~[$rus](?:(?=[$eng]*[а-яё])|(?<=[а-яё].)(?<=[^$rus].))";
$regex .= "|[$eng](?:(?=[$eng]*[а-яё])|(?<=[а-яё].))~u";
preg_match_all($regex, $text, $matches);
$raw = '';
foreach ($matches[0] as $m) {
$raw .= isset($replace[$m]) ? '0' : '1';
}
// Необработанная бинарная строка
$r['raw_data'] = $raw;
// Делим на части начиная с первого вхождения BITS_PREFIX
$r['binary'] = str_split(strstr($raw, BITS_PREFIX), BITS_PER_ID + strlen(BITS_PREFIX));
// Удаляем BITS_PREFIX и переводим результат из двоичной в десятичную систему счисления
$r['decimal'] = array_map('bindec', substr_replace($r['binary'], '', 0, strlen(BITS_PREFIX)));
return $r;
}
// исходный текст
$text = '';
$id = 123;
$enc = encode($text, $replace, $id);
$dec = decode($enc, $replace);
echo "<hr>\n", $enc, "\n<hr>\n";
echo "<pre>", print_r($dec, 1), "</pre>";