На дворе 21 век, а функцию двунаправленной обратимой транслитерации на основе ГОСТ 16876-71 я так и не нашел! Поэтому написал собственную. Если пригодится - помогите и мне, отправив сколько-нибудь монеток на BTC адрес 1QKameueB49uGg387Az1hTKRSWgz7bP8b2

<?php

/**
 * Функция обратимой транслитерации на основе ГОСТ 16876-71
 * @author http://space1000.ru
 * @donate 1QKameueB49uGg387Az1hTKRSWgz7bP8b2
 */

function translit_url($text,$decode = false)
{
  // Split text into array of unicode chars.
  preg_match_all('/./u', $text, $text);
  $text = $text[0];

  $simplePairs = array(
    'а' => 'a'   ,   'л' => 'l'   ,   'у' => 'u'   ,   
    'б' => 'b'   ,   'м' => 'm'   ,   'т' => 't'   , 
    'в' => 'v'   ,   'н' => 'n'   ,   'ы' => 'y'   ,
    'г' => 'g'   ,   'о' => 'o'   ,   'ф' => 'f'   ,
    'д' => 'd'   ,   'п' => 'p'   ,   
    'и' => 'i'   ,   'р' => 'r'   ,   

    'А' => 'A'   ,   'Л' => 'L'   ,   'У' => 'U'   ,
    'Б' => 'B'   ,   'М' => 'M'   ,   'Т' => 'T'   , 
    'В' => 'V'   ,   'Н' => 'N'   ,   'Ы' => 'Y'   ,
    'Г' => 'G'   ,   'О' => 'O'   ,   'Ф' => 'F'   ,
    'Д' => 'D'   ,   'П' => 'P'   ,   
    'И' => 'I'   ,   'Р' => 'R'   ,   
  );
  $complexPairs = array(
    'ж' => 'zh'  ,   'ч' => 'ch'  ,   'х' => 'kh'  ,
    'з' => 'z'   ,   'ц' => 'c'   ,   'к' => 'k'   ,

                                      'я' => 'ja'  ,
                     'щ' => 'shh' ,   'ю' => 'ju'  ,
    'э' => 'eh'  ,   'ш' => 'sh'  ,   'й' => 'jj'  ,
    'е' => 'e'   ,   'с' => 's'   ,   'ё' => 'jo'  ,   

    'Ж' => 'ZH'  ,   'Ч' => 'CH'  ,   'Х' => 'KH'  ,
    'З' => 'Z'   ,   'Ц' => 'C'   ,   'К' => 'K'   ,

                                      'Я' => 'JA'  ,    
                     'Щ' => 'SHH' ,   'Ю' => 'JU'  ,
    'Э' => 'EH'  ,   'Ш' => 'SH'  ,   'Й' => 'JJ'  ,
    'Е' => 'E'   ,   'С' => 'S'   ,   'Ё' => 'JO'  ,   

    'Ь' => "^'"  ,   'Ъ' => "^`"  ,
    'ь' => "'"   ,   'ъ' => "`"   ,   
  );
  $specialSymbols = array(
    "_" => "__",
    "-" => "_-",
    "'" => "_'",
    "`" => "_`",
    "^" => "_^",
    " " => "-",
  );
  $translitLatSymbols = array(
    'a','l','u','b','m','t','v','n','y','g','o',
    'f','d','p','i','r','z','c','k','e','s', 
    'A','L','U','B','M','T','V','N','Y','G','O',
    'F','D','P','I','R','Z','C','K','E','S', 
  );
  $simplePairsFlip = array_flip($simplePairs);
  $complexPairsFlip = array_flip($complexPairs);
  $specialSymbolsFlip = array_flip($specialSymbols);
  $charsToTranslit = array_merge(
    array_keys($simplePairs),
    array_keys($complexPairs)
  );
  $translitTable = array();
  foreach($simplePairs as $key => $val) $translitTable[$key] = $simplePairs[$key];
  foreach($complexPairs as $key => $val) $translitTable[$key] = $complexPairs[$key];
  foreach($specialSymbols as $key => $val) $translitTable[$key] = $specialSymbols[$key];
  $result = "";


  if($decode)
  {
    $char = array();
    $translitDisabled = false;
    for($pos = 0; $pos < count($text); $pos++)
    {
      $char[0] = $text[$pos];
      $char[1] = isset($text[$pos+1]) ? $text[$pos+1] : null;
      $char[2] = isset($text[$pos+2]) ? $text[$pos+2] : null;
      // Decoding specsymbols: [_-'`^ ]
      foreach($specialSymbolsFlip as $key => $val)
      {
        $search = "";
        for($j = 0; $j < strlen($key) ; $j++) $search.= $char[$j];
        if($search == $key)
        {
          $result.= $val;
          $pos += strlen($key) - 1;
          continue 2;
        }
      }
      // Lone '_' symbol disables or enables translitting.
      if($char[0] == '_')
      {
        $translitDisabled = !$translitDisabled;
        continue;
      }
      // When translit is disabled, simply add char to result.
      if($translitDisabled)
      {
        $result.= $char[0];
      }
      else
      {
        if(in_array($char[0],$simplePairs))
        {
          $result.= $simplePairsFlip[$char[0]];
          continue;
        }
        foreach($complexPairsFlip as $key => $val)
        {
          $search = "";
          for($j = 0; $j < strlen($key); $j++) $search.= $char[$j];
          if($search == $key)
          {
            $result.= $val;
            $pos += strlen($key) - 1;
            continue 2;
          }
        }
        // if nothing up worked
        $result.= $char[0];
        continue;
      }
    }
  }
  else
  {
    $translitDisabled = false;
    foreach($text as $char)
    {
      if(in_array($char,array_keys($specialSymbols)))
      {
        $result.= $translitTable[$char];
      }
      elseif(in_array($char,$charsToTranslit))
      {
        if($translitDisabled)
        {
          $result.= "_";
          $translitDisabled = false;
        }
        $result.= $translitTable[$char];
      }
      else
      {
        if(!$translitDisabled
        && in_array($char,$translitLatSymbols))
        {
          $result.= "_";
          $translitDisabled = true;
        }
        $result.= $char;
      }
    }
  }
  return $result;
}