forum.boolean.name

forum.boolean.name (http://forum.boolean.name/index.php)
-   JAVA Micro Edition (http://forum.boolean.name/forumdisplay.php?f=52)
-   -   Сжать текст смс средствами J2me (http://forum.boolean.name/showthread.php?t=7252)

Phantom 28.10.2008 11:11

Сжать текст смс средствами J2me
 
Вот:
http://www.mobilab.ru/articles/94/

Наверно, все это уже читали. Мне нужно реализовать примерно такое же, но я не могу использовать BinaryMessage, так как смс будет отправляться не на мобилу, а на короткий платный номер, где приём и декодирование сообщения будет производить сервер. А смс билинги не поддерживают приём бинарных сообщений. В статье, которую я упомянул вначале, написано, что в обыкновенном сообщении используется 7-и битное кодирование (либо юникод, если встречаются символы, которые не влазят в 7-и битный диапазон). 7 бит - это значит 128 возможных символов. Я взял телефон и начал набирать все возможные символы, которые не переключают месаджбокс в юникод (телефон сименс с75, вверху он показывает сколько ещё можно ввести сообщений, по числу сразу понятно в каком режиме в данный момент набирается смс - юникод или 7-и битная латиница). В итоге я смог набрать больше 130 символов. О_о И кодирование показывает 7-и битное. Как так? Это же невозможно! Возможно ли, что просто телефон неправильно что-то считает и при отправке сообщение перекодируется в юникод и денег с меня снимут как за две смс? Но суть-то не в этом. Дело в том, что билинг принимает только одиночные смс (либо 70 символов в режиме юникода, либо 160 в режиме 7-и бит). А задача такая: нужно реализовать отправку сообщений на русском и английском языках + набор знаков препинания и основных спец символов, но 70 символов катастрафически мало. В той статье описан очень подходящий способ, но, как я уже сказал, билинг не принимает бинарные сообщения. По сути, какая разница, какое кодирование, общий размер данных-то в любом случае 1120 бит. НО! Я не знаю, как правильно представить данные в семибитном виде и скормить их в проге отправщику смс!!! Я вон вообще насчитал в семибитном кодировании больше 130 символов. Короче, помогите, подскажите! Советуйте всё, что только придёт на ум, главное по теме. У меня у брата можно смс бесплатно отправлять (с тела на тел, не в билинг), так что в тестинге можно не ограничиваться и не бояться упасть в минус =)
- - -
Добавил позже:
Вот ещё по теме нашёл:
http://isms.ru/article.shtml?art_7

Phantom 28.10.2008 13:06

Ответ: Сжать текст смс средствами J2me
 
Грубо говоря, задача сводится вот к чему:
1) У меня есть байтовый массив, размером 140 элементов (1120 бит, ровно размер одного смс сообщения), то есть данные, размером 140 байт (что в них, текст, картинка и т. п. - это не важно).
2) Нужно переделать этот массив в строку из 160 символов (в java символы в строке будут в юникоде, но при передаче в мессаджконнектор строка по ходу сама перекодируется в семибитную кодировку), которые позволено использовать при отправке смс на латинице.

Ладно бы, если коды этих символов находились от 0 до 127, но я понятия не имею в каком порядке они в юникоде находятся и все ли из них входят в первые 128 байт! Статья, которую я упомянул в конце предыдущего сообщения вроде как приоткрывает завесу, надо придумывать что-то. Вот только брат, засранец, отключил услугу бесплатных смс сегодня. Теперь смс платные :'(

impersonalis 28.10.2008 13:19

Ответ: Сжать текст смс средствами J2me
 

http://ru.wikipedia.org/wiki/Символы....D 1.82.D1.8C ?

Phantom 28.10.2008 13:52

Ответ: Сжать текст смс средствами J2me
 
Ээээ... Как-то не в тему. Мне спецификация юникода и utf-8 уже во сне снится =) Тут же нужно в семибитную кодировку переделать. Точнее даже преобразовать массив байт в строку, состоящую из символов, которые при использовании в смс преобразуются в семибитное представление при передаче смс. Во как. гг

Phantom 28.10.2008 13:53

Ответ: Сжать текст смс средствами J2me
 
Ой. Огромное сорри. Вторую ссылку в первом посте написал такую же, как и первую. Скопировал не от туда, откуда надо видимо. Исправил. Теперь ссылка та.

Phantom 28.10.2008 14:28

Ответ: Сжать текст смс средствами J2me
 
Так. Кажется придумал как сделать. Подскажите, как в java байты мне в семибитное представление переделать? То есть у меня есть 140 байт в массиве, а мне нужно переделать их в другой массив из 160 элементов, каждый должен иметь вид 0xxxxxxx. Пример:

Было:
b[0] = 00000000
b[1] = 11001100
b[2] = 11111111

Стало:
b[0] = 00000000
b[1] = 00110011
b[2] = 00011111
b[2] = 01110000

Это я схематично объяснил. Короче мне нужно как-то массив байт на биты разложить и их разделить в другой массив, но уже по семь бит. Блин, никогда с подобным не сталкивался, сложно объяснить.

impersonalis 28.10.2008 17:28

Ответ: Сжать текст смс средствами J2me
 
http://ru.wikipedia.org/wiki/UUE ?!

Phantom 28.10.2008 17:34

Ответ: Сжать текст смс средствами J2me
 
ВО!!! Там пример очень хороший! Где "Пример кодирования" примерно так мне и надо сделать как-то! Как мне такое в Java замутить?
- - -
А ведь в base64 похожая система, да? Тут где-то либа для мидлет паскаля была для этого, попробую её декомпильнуть.

Phantom 28.10.2008 18:41

Ответ: Сжать текст смс средствами J2me
 
Вот блин. Сейчас я буду жёстко ламерить. Нифига не понял эту строку:
head=bytes[0]&0xff|bytes[1]<<8&0xff00;
Видимо какие-то операции с битами. Объясните плиз, как оно работает или дайте ссылку какую-нибудь полезную, желательно на русском.

impersonalis 28.10.2008 19:04

PHP код:

charUUEcode(char *in,unsigned size){
    
unsigned code_size=(size/double(3)+1)*4+1;
    
char *out=new char[code_size];
    
unsigned char s[3];
    
unsigned char c[4];
    
unsigned i,j,k;

    
k=0;
    for(
i=0;i<size;i+=3){

        for(
j=0;j+i<size && j<3;j++){
            
s[j]=in[i+j];
        }
        for(;
j<3;j++)
            
s[j]=0;

        
c[0]=(s[0]&0xFC)>>2;
        
c[1]=((s[0]&0x03)<<4)+((s[1]&0xF0)>>4);
        
c[2]=((s[1]&0x0F)<<2)+((s[2]&0xC0)>>6);
        
c[3]=(s[2]&0x3F);

        for(
j=0;j<4;j++)
            
c[j]+=32;

        for(
j=0;j<4;j++)
            
out[k+j]=c[j];
        
k+=j;

    }
    
out[k]=0;

    return 
out;


PHP код:

charUUEdecode(char *in,unsigned &size){
    
unsigned code_size=(size/double(4)+1)*3+1;
    
char *out=new char[code_size];
    
unsigned char c[3];
    
unsigned char s[4];
    
unsigned i,j,k;

    
k=0;
    for(
i=0;i<size;i+=4){
        for(
j=0;j+i<size && j<4;j++){
            
s[j]=in[i+j];
        }
        for(;
j<4;j++)
            
s[j]=0;

        
c[0]=s[0]-32;
        
c[1]=s[1]-32;
        
c[0]<<=2;
        
c[0]|=(c[1]>>4)&0x03;
        
c[1]<<=4;
        
c[2]=s[2]-32;
        
c[1]|=(c[2]>>2)&0x0F;
        
c[2]<<=6;
        
c[2]|=(s[3]-32)&0x3F;


        for(
j=0;j<3;j++)
            
out[k+j]=c[j];
        
k+=j;


    }
    
out[k]=0;
    
size=k;

    return 
out;


это вот на С++

Цитата:

Сообщение от Phantom_wc (Сообщение 89690)
Вот блин. Сейчас я буду жёстко ламерить. Нифига не понял эту строку:
head=bytes[0]&0xff|bytes[1]<<8&0xff00;
Видимо какие-то операции с битами. Объясните плиз, как оно работает или дайте ссылку какую-нибудь полезную, желательно на русском.

& - как парвило коньюнкция
| - дизъюнкция
<< - сдвиг влево

Phantom 28.10.2008 19:44

Ответ: Сжать текст смс средствами J2me
 
Цитата:

& - как парвило коньюнкция
| - дизъюнкция
<< - сдвиг влево
Слова знакомые, но что они обозначают и как это на практике применять - вообще хз =) Пойду гуглить и википедить.

Phantom 28.10.2008 21:41

Ответ: Сжать текст смс средствами J2me
 
Прочитал я про конъюнкцию и дизъюнкцию. Круто! Как я раньше про такое не слышал??? Это ж такие интересные штуки можно вытворять!!! Сейчас ещё про сдвиги почитаю!

Phantom 29.10.2008 19:32

Ответ: Сжать текст смс средствами J2me
 
Так. Работа идёт. Сейчас нужно сделать массив из 128 символов, которые допускается отправлять в смс в режиме семибитки. Список, который находится по ссылке из первого поста не катит. С ним точно что-то не так. Если я беру из него все 128 символов, и вставляю в редактор смс, то телефон включает режим юникода =( Что делать? У меня тупая просьба. Попробуйте ввести в редакторе смс все символы, которые только позволяет телефон, и которые не переводят редактор в режим юникода. Напомню, в режиме семибитки в одно смс влазит 160 символов, а в режиме юникода - 70. Надеюсь на помощь. Потому что в нете не нашёл ничего путного =(

Phantom 30.10.2008 01:03

Ответ: Сжать текст смс средствами J2me
 
Ура, товарищи!!! Нашёл статью: http://www.rattler.kiev.ua/node/16
Она пролила на всё свет!!! Теперь всё встало на свои места!

Phantom 30.10.2008 16:48

Ответ: Сжать текст смс средствами J2me
 
Так. В таблице, которая находится в википедии, ошибка. Там регистр одного символа не верен. Надо "з" вместо "З". 127 символов, все кроме [ESC] подходят! И отправляются в одиночном смс. Но вот незадача. Я не знаю, что за [ESC] символ. Если верить википедии, то это цитирую:
Цитата:

In the ASCII character code, the character ESC with decimal code 27 and hexadecimal code 1B.
И на самом деле в моём любимом редакторе Notepad2 этот символ обозначается как [ESC]. Но при вставливании этого символа в сообщение (хоть программно, хоть руками через буфер обмена в текстовый редактор сообщения), сообщение переключается в режим юникода. В статье, в предыдущем посте написано, что этот символ используется для ввода некоторых дополнительных символов, например "[ESC](" преобразуется в "{", "[ESC]=" в "~"... Если, конечно, я вручную такую последовательность введу, то они не преобразуются, преобразование происходит на уровне прошивки телефона видимо. То есть я сразу ввожу { или ~, но при передачи сообщения, эти символы принимают вид этих последовательностей. И, видимо, ВНЕ последовательностей одиночный символ [ESC] использовать нельзя. У кого есть какие мысли на этот счёт? Можно использовать вместо него { или ~, ну или вот ещё символы, которые можно закодировать последовательностью с [ESC]: }^\[]|€, но в таком случае один из 128 символов будет иметь размер в два символа. То есть нельзя наперёд сказать, что в отведённый под смс размер в 160 символов влезет именно 160 символов. А если всё сообщение будет состоять из кучи { (либо }^\[]|€), то в сообщение влезет только 80 символов. То есть никакой универсальности, в общем, это очень неудобно. Кто что посоветует?

impersonalis 30.10.2008 20:07

Ответ: Сжать текст смс средствами J2me
 
Цитата:

То есть никакой универсальности, в общем, это очень неудобно.
Ну а ты как думал?
совет:http://forum.boolean.name/showpost.p...7&postcount=30

Phantom 30.10.2008 20:21

Ответ: Сжать текст смс средствами J2me
 
Нифига ничего не понял =(
В джаве нет прямого доступа к отправщику смс. Текст смс скармливать надо в любом случае в юникоде. И если в тексе символы позволяют быть закодированными семью битами, то телефон сам уже кодирует. То есть видимо я пытаюсь ESC символ скормить, но он не может быть в одиночку использован при семибитном кодировании, поэтому телефон решает, что нужно текст использовать в юникоде. Возможно, это ещё от телефона и/или джава машины зависит. Блин... Что же делать-то? Твой совет я нифига не понял =(

Phantom 31.10.2008 02:46

Ответ: Сжать текст смс средствами J2me
 
Сделал вместо ESC тильду. Первые тесты показали неплохой результат. Пример:
"Штиль - ветер молчит,
Упал белой чайкой на дно.
Штиль - наш корабль забыт,
Один в мире, скованном сном.

Между всех времён
Без имён и лиц
Мы уже не ждём,
Что проснётся бриз!"
Данный текст, набранный в смс, занимает три смс сообщения. А этот же текст, пропущенный через мою функцию выглядит примерно так:
"цa_$n,m0ΔTBPX0q5dΦk/r3їШXи)3Dl.@I#DlΞ$їC'7WyB"йЦYZaPш,Λ9@@%ЦXЖ@Πi5WxpB щlй0aи$uXDQїЎ
Ξ8eD&NΘЬС?Fйш_жЎHE+0ΦЈ& ~/p_#lΔ2ЈДи,Π!5?F~XL0ДщEXΣ¤ҐΞkцС_kмPЖDlиH§XйЈЈv"
И ВЛАЗИТ В ОДНО СМС!!!
Я мега крут!

Phantom 31.10.2008 02:49

Ответ: Сжать текст смс средствами J2me
 
Форум испаганил почему-то некоторые символы. Непонятно откуда появились всякие "ц", "Д", "ш", "ж"... Это я к тому, что моя функция выдаёт нормальные символы, которые не переключают смс-редактор в режим юникода, это всё баг форума. =)

impersonalis 31.10.2008 17:29

Ответ: Сжать текст смс средствами J2me
 
Так-так. Что придпримите далее?
*читаю, как начуно-популярный сериал смотрю - все серии*

Phantom 31.10.2008 18:04

Ответ: Сжать текст смс средствами J2me
 
Ой, ёлки, сколько спасибок поставили. Вы это погорячились. Я пока на PHP написал сам алгоритм, так как в нём много лучше ориентируюсь, чем в Java. Ещё предстоит довести до ума и портировать на Java. Так что ещё куча вопросов, наверно, возникнет. =)

Phantom 04.11.2008 03:45

Ответ: Сжать текст смс средствами J2me
 
Всё. Готово практически. Осталось пару строк в класс вписать! Вот только не знаю как это делается. Нужно в цикле пробежать строку посимвольно, получая код очередного символа. Из потока я умею побайтно читать, а вот как из строки посимвольно - не знаю.

Piligrim 04.11.2008 15:17

Ответ: Сжать текст смс средствами J2me
 
s.charAt(int)
а заменять удобно с помощью s.replace(char, char)

Phantom 04.11.2008 20:32

Ответ: Сжать текст смс средствами J2me
 
Сорри, я уже сделал, но забыл отписаться =) Только пока не работает как надо. Сейчас вот до ума довожу.

abcdef 24.12.2008 21:49

Ответ: Сжать текст смс средствами J2me
 
Phantom_wc - я когда-то делал аналогичный алгоритм, но в MIDletPascal, неохота переписывать на java,.. думаю получилось просто это можно взять за основу, и добавить в алгоритм кодирования обход недопустимых символов..
Код:

var
  buf : array[0..4096] of boolean;
  bit : array[0..7] of integer;
  max : integer;
  id_in,id_out,id_dec : integer;
  convCmd : command;


function ansiToUtf(s : string) : string;
var  {rus_ansi to UTF8}
  i,ch : integer;
begin
  for i := 0 to length(s)-1 do
  begin
    ch := ord(getChar(s,i)) and 255;
    if (ch>=192) then  s := setChar(s,chr(ch+848),i);
    if (ch=168)  then  s := setChar(s,chr($0401),i);
    if (ch=184)  then  s := setChar(s,chr($0451),i);
  end;
  ansiToUtf := s;
end;


function utfToAnsi(s : string) : string;
var  {UTF8 to rus_ansi}
  i,ch : integer;
begin
  for i := 0 to length(s)-1 do
  begin
    ch := ord(getChar(s,i));
    if (ch>255) then  s := setChar(s,chr(ch-848),i);
    if (ch=$0401) then  s := setChar(s,chr(168),i);
    if (ch=$0451) then  s := setChar(s,chr(184),i);
  end;
  utfToAnsi := s;
end;


procedure toBits(s : string; maxb : integer);
var
  i,j,b : integer;
begin
  max:=0;
  for i:=0 to 4096 do buf[i]:=false;
  for i:=0 to length(s)-1 do
  begin
    b:=ord(getChar(s,i));
    for j:= maxb{7} downto 0 do
    begin
      if (b and bit[j])<>0 then buf[max]:=true;
      max:=max+1;
    end;
  end;
end;


function fromBits(maxb : integer) : string;
var
  i,j,b : integer;
  s : string;
begin
  i:=0;
  s:='';
  while i<max do
  begin
    b:=0;
    j:=maxb;
    while (i<max) and (j>=0) do
    begin
      if buf[i] then b:=(b or bit[j]);
      i:=i+1;
      j:=j-1;
    end;
    s:=s+chr(b);
  end;
  fromBits:=s;
end;


begin
  bit[0]:=1;
  bit[1]:=2;
  bit[2]:=4;
  bit[3]:=8;
  bit[4]:=16;
  bit[5]:=32;
  bit[6]:=64;
  bit[7]:=128;
  showForm;
  id_in := formAddTextField('IN', 'Привет! это тестовая программка от arT (c). e-mail: [email protected]', 512, TF_ANY);
  convCmd := createCommand('next', CM_OK, 1);
  addCommand(convCmd);
  repeat delay(100); until getClickedCommand=convCmd;
  removeCommand(convCmd);
  //////
  toBits(utfToAnsi(formGetText(id_in)),7);
  id_out := formAddTextField('OUT', fromBits(6), 1024, TF_ANY);
  //////
  toBits(utfToAnsi(formGetText(id_out)),6);
  id_dec := formAddTextField('DECODE', ansiToUtf(fromBits(7)), 512, TF_ANY);
  repeat delay(100); until false;
end.


Phantom 25.12.2008 07:43

Ответ: Сжать текст смс средствами J2me
 
Ы. Да я уже сделал =) Совсем забыл, что у меня тут тема есть на эту тему =) Оказалось в итоге, что зря я мучился, биллинг запретил отправку смс с подменой номера :-(


Часовой пояс GMT +4, время: 19:53.

vBulletin® Version 3.6.5.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot