2014-10-03 5 views
2

У меня полная потеря, попытка конвертировать десятичную строку, а не oct, просто равную десятичную, которая варьируется в значении символов до простого текста.Функция PHP для преобразования десятичного ASCII в символ ASCII

Строка будет выглядеть следующим образом: 495051979899100 (123abcd)

я мог бы использовать Chr() весь день, если у меня был способ предсказать, что строка будет содержать, но я на самом деле нет, так что должно Я делаю?

+0

Я предполагаю, что это будет двухэтапный процесс. Сначала преобразуйте десятичную строку в шестнадцатеричную, а затем начните вытягивать по 2 символа за раз и преобразуйте их в эквивалент символов. – Erik

+1

Как вы можете узнать, есть ли 4 цифры - комбинация 3/1, 2/2 или 1/3? –

+2

Я думаю, что первая проблема - это неоднозначность. Как вы подразделяете '456' на' 45' и '6' или' 4' и '56'. –

ответ

3

Ваш вопрос неоднозначен в том смысле, что без каких-либо предположений входная строка может привести к экспоненциальному количеству строк вывода, которые удовлетворяют всем ограничениям.

Мы делаем предположение, что с ASCII вы имеете в виду читаемые (не управляющие части) ascii. Таким образом, любое действительное значение ascii находится между 32 и 128. В результате вы знаете, что если первые два символа представляют значение, строго меньше 32, оно будет в диапазоне 100+.

Ваш алгоритм должен делать две вещи одновременно:

  • Считать первые два символа.
  • Если значение меньше 32, тогда значение находится в диапазоне 100+, поэтому прочитайте три символа и конвертируйте, если не в диапазоне -100, су конвертируйте два символа.

Или в PHP:

$s = "495051979899100"; 
$n = strlen($s); 
$result = ""; 
for ($x=0; $x<=$n; $x += 2) { 
    $temp = intval(substr($s,$x,2)); 
    if($temp < 32) { 
     $temp = intval(substr($s,$x,3)); 
     if($temp > 128) { 
      die "Assumption error"; 
     } 
     $x++; 
    } 
    $result .= chr($temp); 
} 
echo $result; 
+0

стоит отметить, что если символ, который меньше 32, попадает в эту систему, система терпит неудачу. – Sharky

+0

@Sharky: Я полностью согласен, но это единственный способ сделать это, так как в противном случае система неоднозначна, поэтому она может отображать экспоненциальное число строк. Я добавлю предположение на ответ. –

+0

да, это классическая ситуация, когда вы ** должны ** перейти в корень проблемы и исправить причины, а не добавлять больше сложности, например, в этой ситуации, угадывать вещи. – Sharky

2

Yep, написал почти тот же код

$str = '495051979899100'; 
$ind = 0; $out = ''; 
while($ind < strlen($str)) 
{ 
    $two = substr($str, $ind, 2); 
    if ($two >= 32) { 
     $out .= chr($two); 
     $ind += 2; 
    } else { 
     $out .= chr(substr($str, $ind, 3)); 
     $ind += 3;   
    } 
} 

echo $out; 
2

Мой необычный способ с ограничением, что символ может быть от 32 до 128.

$value = '495051979899100'; 
preg_match_all('/3[2-9]|[4-9][0-9]|1[0-1][0-9]|12[0-8]/', $value, $matches); 
var_dump(implode(array_map('chr',$matches[0]))); 
// string(7) "123abcd" 
+0

Конечный автомат разрешает каждую задачу, не так ли? Я открывал сообщение, просто набрав тот же ответ :) – mudasobwa

+0

@mudasobwa, он короткий, но нечитабельный. Трудно определить ограничение в этом коде. – sectus

+0

Вы действительно думаете, что это _less_ удобочитаемо, чем танцы вокруг 'if' 'и' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' Это пример _very_ readable regexp, потому что он точно воспроизводит состояния в FSM. – mudasobwa

Смежные вопросы