// Размер 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>";