Вопрос: кодировка на выходе от ldap_explode_dn (PHP)

Для тех, кто хочет сделать мир лучше.
Ответить
Сообщение
Автор
Аватара пользователя
y3k.xeon
Лейтенант
Лейтенант
Сообщения: 100
Зарегистрирован: 24.01.2006
Откуда: Беларусь
Благодарил (а): 132 раза
Поблагодарили: 1 раз
Контактная информация:

#1 Сообщение 21.08.2012, 15:06

Может кто знает, помогите.
Cуть такова, есть функция ldap_explode_dn (PHP), разделяет DN на части-компоненты, которые возвращает как массив строк.
Проблема: на вход идёт обычная UTF-8 строка, которая содержит этот самый DN, а вот на выходе массив строк непонятного формата.

Пример
Вход:

Код: Выделить всё

string(81) "CN=Ололошка,OU=Русс\,кое,OU=te\\st%,OU=Users,OU=eluni,DC=ad,DC=vsu"
На выходе:

Код: Выделить всё

array(8) {
  ["count"]=>
  int(7)
  [0]=>
  string(48) "\D0\9E\D0\BB\D0\BE\D0\BB\D0\BE\D1\88\D0\BA\D0\B0"
  [1]=>
  string(45) "\D0\A0\D1\83\D1\81\D1\81\2C\D0\BA\D0\BE\D0\B5"
  [2]=>
  string(8) "te\5Cst%"
  [3]=>
  string(5) "Users"
  [4]=>
  string(5) "eluni"
  [5]=>
  string(2) "ad"
  [6]=>
  string(3) "vsu"
}
В общем кто знает подскажите что это за зверь:

Код: Выделить всё

string(48) "\D0\9E\D0\BB\D0\BE\D0\BB\D0\BE\D1\88\D0\BA\D0\B0"
и каким каноничным способом это сконвертировать в обычную строку.
Изображение

MOZGIII
Разработчик
Разработчик
Сообщения: 910
Зарегистрирован: 09.01.2009
Откуда: Переезжаю в /dev/null
Благодарил (а): 7 раз
Поблагодарили: 65 раз
Контактная информация:

#2 Сообщение 21.08.2012, 15:59

y3k.xeon
Похоже на UFT-8 или 16.
C php.net
http://php.net/manual/ru/function.ldap-explode-dn.php

Код: Выделить всё

<?php 
    /** 
     * Parse, and format a DN string to Array 
     * 
     * Read a LDAP DN, and return an array keys 
     * listing all similar attributes. 
     * 
     * Also takes care of the character escape and unescape 
     * 
     * Example: 
     * CN=username,OU=UNITNAME,OU=Region,OU=Country,DC=subdomain,DC=domain,DC=com 
     * 
     * Would normally return: 
     * Array ( 
     *     [count] => 9 
     *     [0] => CN=username 
     *     [1] => OU=UNITNAME 
     *     [2] => OU=Region 
     *     [5] => OU=Country 
     *     [6] => DC=subdomain 
     *     [7] => DC=domain 
     *     [8] => DC=com 
     * ) 
     * 
     * Returns instead a manageable array: 
     * array ( 
     *     [CN] => array( username ) 
     *     [OU] => array( UNITNAME, Region, Country ) 
     *     [DC] => array ( subdomain, domain, com ) 
     * ) 
     * 
     * 
     * @author gabriel at hrz dot uni-marburg dot de 05-Aug-2003 02:27 (part of the character replacement) 
     * @author Renoir Boulanger 
     * 
     * @param  string $dn          The DN 
     * @return array 
     */ 
    function parseLdapDn($dn) 
    { 
        $parsr=ldap_explode_dn($dn, 0); 
        //$parsr[] = 'EE=Sôme Krazï string'; 
        //$parsr[] = 'AndBogusOne'; 
        $out = array(); 
        foreach($parsr as $key=>$value){ 
            if(FALSE !== strstr($value, '=')){ 
                list($prefix,$data) = explode("=",$value); 
                $data=preg_replace("/\\\\\\([0-9A-Fa-f]{2})/e", "''.chr(hexdec('\\\\1')).''", $data); 
                if(isset($current_prefix) && $prefix == $current_prefix){ 
                    $out[$prefix][] = $data; 
                } else { 
                    $current_prefix = $prefix; 
                    $out[$prefix][] = $data; 
                } 
            } 
        } 
        return $out; 
    } 
?>

Аватара пользователя
y3k.xeon
Лейтенант
Лейтенант
Сообщения: 100
Зарегистрирован: 24.01.2006
Откуда: Беларусь
Благодарил (а): 132 раза
Поблагодарили: 1 раз
Контактная информация:

#3 Сообщение 21.08.2012, 16:30

MOZGIII
Я понимаю что там коды UTFа, только я хотел узнать конкретно что за формат экранирования такой: \<hexcode>\<hexcode>\<hexcode>.
И кстати прежде чем писать отгуглил по этому поводу от и до, и маны на php.net по функциям перечитал, а вот в комменты глянуть как то забыл, спс за напоминание.
Ну да ладно, видимо за неимением лучшего придётся писать неканонично (или самому парсить DN, или самому конвертить эту строку).

p.s.
забыл написать что эти строки неплохо конвертятся в обычные с помощью pack("H*", stripslashes($string)), но такая конструкция требует чтобы $string состояла только и только из этих кодов, а там если латинские символы, то они идут обычной записью, поэтому такой способ мне не подошёл

update:
вобщем вопрос конвертирования решён, выбрал такой вариант: preg_replace("/\\\([0-9A-Fa-f]{2})/e", "''.chr(hexdec('\\1')).''", $string)
Изображение

MOZGIII
Разработчик
Разработчик
Сообщения: 910
Зарегистрирован: 09.01.2009
Откуда: Переезжаю в /dev/null
Благодарил (а): 7 раз
Поблагодарили: 65 раз
Контактная информация:

#4 Сообщение 21.08.2012, 17:33

Формат экранирования простой: \<hex-код байта>, парсим по два - получаем 2 байта, это один юникодный символ. Ду дольше просто преобразование short -> unicode, в зависимости от кодировки (иногда нужно байты местами поменять - ntohs-подобная операция).

Аватара пользователя
y3k.xeon
Лейтенант
Лейтенант
Сообщения: 100
Зарегистрирован: 24.01.2006
Откуда: Беларусь
Благодарил (а): 132 раза
Поблагодарили: 1 раз
Контактная информация:

#5 Сообщение 22.08.2012, 01:04

MOZGIII
Да это понятно было, просто думал может быть есть некое каноничное имя для данного экранирования и стандартная функция для разбора.
Но как я уже написал, спс за ссылку на комменты на php.net, взял лучшее оттуда за неимением стандартных функций.
Изображение

Ответить