как конвертнуть 2 байта UTF-16 из java в UTF-8 для вывода на странице?

  • Автор темы Tertium Organum
  • Дата начала

Tertium Organum

Guest
как конвертнуть 2 байта UTF-16 из java в UTF-8 для вывода на странице?

пишу связку java-php. С помощью curl передаю строку из явы. В яве они в UTF-16, разбиваю на два байта, передаю в литеральном виде: например слово 'Это' передается как 042D 0442 043E.
На пхп разбираю в массив целых чисел - array(4, 45, 4, 66, 4, 62)
Теперь надо из целочисленного массива, где по два байта на символ, получить UTF-8 для вывода на странице (<meta http-equiv="Content-Type" content="text/html; charset=utf-8">).
По идее мне подходит iconv('UTF-16','UTF-8',$str), но никак не пойму, как эту $str из моего массива соорудить.

Порылся по форуму, много интересного пишут, но все не то. Кажется ответ очень простой и он где-то рядом, но никак не могу нащупать.
 

AmdY

Пью пиво
Команда форума
делай iconv для строки пришедшей от другого скрипта и работай дальше уже со строкой в utf-8
про массивы вообще что-то непонятное
 

Tertium Organum

Guest
Нет никакого другого скрипта. Я говорил про Java - не про JavaScript.
Насчет массива - это техническое требование той стороны, что на java.
http://phpclub.ru/faq/encodings смотрел в первую очередь, много полезного. Но не совсем то.

Еще раз.
Вопрос пока не в кодировках.

Скажем проще:
есть массив целых чисел (byte, каждое значение: 0-255).
Как получить строку, пригодную для iconv?

пытался форматировать в:
"\u042D\u0442\u043E"
"%042D%0442%043E"
"&amp;#042D;&amp;#0442;&amp;#043E;"
Пробовал еще некоторые варианты.
Бесполезно.
Никто не сталкивался? Интересует вообще как представляется UTF16 строка в обычной php-строке, если не так, как я пытался форматировать?
 

DiMA

php.spb.ru
Команда форума
> Никто не сталкивался?

да ваще никто, ты первооткрыватель!

chr ord printf pack unpack

------------

"\u042D\u0442\u043E" - для записи юникода РУКАМИ В КОДЕ (хотя можно тупо извратиться и через эвал прогнать)
"%042D%0442%043E" - для УРЛа
"&#042D;&#0442;&#043E;" - для ХТМЛя

пхп (как программа, а не человек) ко всем 3м вариантам не имеет отношения
 

Tertium Organum

Guest
туплю
chr - аски символ (при чем тут?)
ord - код аски (при чем тут?)
printf и подобные, аргумента %S как в сях нет (при чем тут)

за pack unpack - спасибо, пороюсь

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

в пхп на самом деле в теле запроса уходит здоровая шапка криптованных данных, и там кое-где закодированы строки
 

DiMA

php.spb.ru
Команда форума
> chr - аски символ (при чем тут?)

При том, что ты именно это и спросил. Прогоняешь в цикле свою строку и через chr/ord делаешь что хочешь (аналог - printf). pack/unpack - тоже самое, без циклов, в одну команду, но нужно почитать ман.

-~{}~ 07.04.09 12:09:

> Интересует вообще как представляется UTF16

Как же, как и везде - строка по 2 байта на символ (байты могут меняться, по старшинству, UTF-16BE или UTF-16LE). Другой вопрос, как эти строки обрабатывать, какие функции доступа применять и т.д. - как однобайтные или юникод.
 

Grezz

Новичок
Tertium Organum, а может просто в java коде передавать UTF-8?
 

Tertium Organum

Guest
Grezzне, в два раза больше данных, до 4 байт в utf8. Но может и так, если не выйдет, как я хочу.
--------
DiMA
chr/ord работают с аски символами, не юникод. это первое за что я взялся, но не понял с какого края подступиться. пробовал давать ей двубайтовый номер символа, понятное дело - не то

образование у меня сёвое, поэтому я так понимаю, что пхпшная строка внутри содержит массив однобайтных символов (на сях unsigned byte). Если так, то закодировать в нее утф8 так, чтобы воспринимал браузер, можно тегами &#XXXX;

wide_char или UTF-16 - это массив типа unsigned short, поэтому в однобайтный массив воткнуть его конечно можно, но встречающиеся зачастую в старших байтах нули разорвут строку. Поэтому опять же впечатление такое, что надо кодировать типа &#XXXX.

Было бы удобно если б можно было UTF16 строку закодировать в обычную кодами символов и тегами, а потом получить из нее такую же закодированную для UTF8, чтобы вывести в браузер.

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

Спасибо, на некоторые мысли натолкнуло общение в этой ветке, сейчас буду пробовать. обязательно отпишусь по факту, вдруг кому интересно.
 

Grezz

Новичок
Автор оригинала: Tertium Organum
Grezzне, в два раза больше данных, до 4 байт в utf8. Но может и так, если не выйдет, как я хочу.
UTF-16 вообще то тоже для одного символа может и 4 байта занять, хотя и при использовании UTF-8 и при использовании UTF-16 это случается крайне редко - только при использовании экзотических символов, а в большинстве случаев UTF-8 требует примерно равного, либо меньшего (если в строке присутствуют символы из младшей части ascii таблицы) кол-ва байт.
 

Tertium Organum

Guest
UTF-16 жестко 2 байта в яве, это вообще почти родной тип и unsigned short там является char - 0-65535.
 

dimagolov

Новичок
Tertium Organum, iconv пользовать религия не позволяет? или вообще отдавать браузеру в UTF-16, раз уж она такая родная для тебя? Для MySQL родная, правда, UCS-2, но еще вопрос, надо ли тебе что-то кроме этого.
 

Grezz

Новичок
Автор оригинала: Tertium Organum
UTF-16 жестко 2 байта в яве, это вообще почти родной тип и unsigned short там является char - 0-65535.
Почти верно.
Char в жаве 2 байта, а вот некоторые символы согласно стандарту на UTF-16 могут представляться в 4-х байтном формате, то есть представляться двумя последовательностями по два байта. Но что - то мы отклоняемся от темы....

а вообще вот от сюда и до...
 

Tertium Organum

Guest
dimagolov
Вопрос в том как сделать строку UTF-16 из байтового массива
понятно, что в пхп байтов и тд
вопрос как был так и остался.
Со всем уважением, пока здесь только указания на мою некомпетентность (каковая безусловно в некотором смысле имеет место), ссылки на доки (которые прочитаны) и смутные намеки, что я что-то спрашиваю не так.

Ответом на вопрос может быть только кусок кода который в частности делает из array(4, 45, 4, 66, 4, 62) строку в UTF-8 "Это" и вообще конвертит любые строки, представленные в виде массива байтов, в UTF-8.

Как только проблему решу, отпишусь, тогда может станет понятнее, о чем я спрашивал

2Grezz:
само собой, не первый день в яве :)
 

Grezz

Новичок
Автор оригинала: Tertium Organum
Ответом на вопрос может быть только кусок кода который в частности делает из array(4, 45, 4, 66, 4, 62) строку в UTF-8 "Это" и вообще конвертит любые строки, представленные в виде массива байтов, в UTF-8.
да пожалуйста

$arr = array(4, 45, 4, 66, 4, 62);
$arr = array_map('chr', $arr);
$str = implode('', $arr);
$str = iconv('UTF-16', 'UTF-8', $str);
echo $str;

Просто не понятно, зачем эти пляски с бубном если всё банально решается на java строчкой типа str.getBytes('UTF-8'); ?
 

DiMA

php.spb.ru
Команда форума
Tertium Organum
есть базовые фукнции:
$sting[0...N] или substr()
chr()
ord()
все остальные функции операции со строками можно родить, используя только эти 3 метода. Раз ты пишешь о массиве чисел (это не я выдумал, см 1 сообщение) - chr/ord самое то. Ну, еще hexdec =)

Правильный ответ: pack/unpack + iconv. Или вот как выше сообщением.
 

Tertium Organum

Guest
Grezz
То что надо, и что важнее - теперь ясно что со строками. Я пробовал и такой вариант (chr в цикле), но одно на другое наложилось (баги) и мне показалось, что ничего не вышло.

Касательно кодирования в utf-8 в яве - в моей задаче очень важное ограничение: не выделять память. Поэтому в частности функции конверсии пришлось писать руками и работать с массивами символов, а не строками. А ф-ция getBytes - выделяет память (по исходникам явы смотрел). Так что придется удовлетвориться танцами с бубном, пусть пхпшная часть будет и не такая эффективная. В высокопроизводительных системах, не поверите, всегда так. Даже на яве (тут ограничение не мое, мог бы - писал на сях).

Всем спасибо, намного понятнее стало жить! :)
 
Сверху