Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Расчет контрольных сумм для ГИС ЖКХ / 12 сообщений из 12, страница 1 из 1
15.10.2016, 11:22
    #39327496
Расчет контрольных сумм для ГИС ЖКХ
Добрый день уважаемые пользователи, помогите решить задачу:

После генерации строки номера ЕЛС со 2-го по 10-ый символ система рассчитывает контрольную сумму следующим образом:
1. каждый кириллический символ из ЕЛС должен быть приведен к числовому виду, для этого необходимо код символа в кодировке UTF-8 перевести из двоичного представления в десятичное;
2. Каждая цифра из ЕЛС или число, соответствующее кириллическому символу из ЕЛС, умножается на номер своей позиции в номере. ЕЛС, при этом позиции отсчитываются с конца номера - справа налево;
4. полученные произведения суммируются;
5. полученная сумма делится на 10;
6. Остаток от деления является контрольной суммой.
...
Рейтинг: 0 / 0
15.10.2016, 11:23
    #39327497
Расчет контрольных сумм для ГИС ЖКХ
Пример номера: 40АА000177
...
Рейтинг: 0 / 0
15.10.2016, 12:55
    #39327521
andrey_anonymous
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Расчет контрольных сумм для ГИС ЖКХ
Модераторы, этому место в форуме "работа"...
ТС: изучаем матчасть.
Конвертировать в UTF-8 - функция convert для строк и utl_raw.convert для raw/blob
Получить конкретный символ из строки: функция substr
Получить код символа: функция ascii
Умножить число на число: оператор *
Сложить: оператор +
получить остаток от деления: функция mod

Сложность представляет лишь освоение и правильное применение функции convert, поскольку по-хорошему требует осознания довольно объемного Globalization Support Guide.
С другой стороны, не так много ораклоидов вообще владеют этой темой на уровне выше "установи NLS_LANG как в БД" - можно заработать полезный скилл.
...
Рейтинг: 0 / 0
16.10.2016, 08:11
    #39327683
Elic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Расчет контрольных сумм для ГИС ЖКХ
Нубик-БобикПосле генерации строки номера ЕЛСПервоисточник является ДСП и скрыт от интернетов?
...
Рейтинг: 0 / 0
17.10.2016, 09:23
    #39327969
Расчет контрольных сумм для ГИС ЖКХ
andrey_anonymous, что то пошло не так:

select
ascii(convert('А','UTF8')) a
,ascii(convert('Б','UTF8')) b
from dual

REUSLT:
208|208
...
Рейтинг: 0 / 0
17.10.2016, 11:32
    #39328061
orawish
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Расчет контрольных сумм для ГИС ЖКХ
Нубик-Бобикandrey_anonymous, что то пошло не так:

select
ascii(convert('А','UTF8')) a
,ascii(convert('Б','UTF8')) b
from dual

REUSLT:
208|208
конечно, не так (то, что не лезет в один байт ничто длиннее байта )
Код: plsql
1.
2.
3.
4.
5.
6.
select
 ascii(convert('А','UTF8')) 
,ascii(convert('Б','UTF8')) 
,dump(convert('А','UTF8')) 
,dump(convert('Б','UTF8')) 
from dual;
...
Рейтинг: 0 / 0
17.10.2016, 14:02
    #39328188
Расчет контрольных сумм для ГИС ЖКХ
orawish, а как правильно получить эти самые конечные 208145 из Typ=1 Len=2: 208,145 ?
...
Рейтинг: 0 / 0
17.10.2016, 15:08
    #39328269
Сергей Арсеньев
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Расчет контрольных сумм для ГИС ЖКХ
Нубик-Бобикorawish, а как правильно получить эти самые конечные 208145 из Typ=1 Len=2: 208,145 ?
это приведено для примера. Еслиб Вы посмотрели во что превратились символы прийдя из Вашей 1251 в utf-8 то увидели бы что там появились строки по два символа:
Код: plsql
1.
2.
3.
select convert('А','UTF8') s from dual
 union all
select convert('Б','UTF8') s from dual;


другими словами Вам сначала следуем разбить строку на символы, а потом посчитать в коды каждый символ полученной строки.
Кроме того, надо иметь ввиду, что в utf-8 длина строки может оказаться больше и выйти за границы диапазона, а значит преобразовывать лучше уже разбив на последовательность символов и потом опять разбив на символы.
:)
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
with t as (
select 'А' s from dual
 union all
select 'Б' s from dual
 union all
select 'еЁ' s from dual
)
select s,ascii(column_value) c from (
select rownum r2,t3.*,cast(multiset(select substr(t3.c,level,1) from dual connect by substr(t3.c,level,1) is not null) as sys.odcivarchar2list) v2
  from (
select rownum r,s,convert(column_value,'UTF8') c from (
select t1.*,cast(multiset(select substr(t1.s,level,1) from dual connect by substr(t1.s,level,1) is not null) as sys.odcivarchar2list) v
  from t t1) t2,table(v)
) t3),table(v2)
order by r,r2


Но на самом деле проще написать свою функцию, которая будет на PL/SQL (или встроенной java) пересчитывать код строки.
...
Рейтинг: 0 / 0
17.10.2016, 15:27
    #39328297
orawish
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Расчет контрольных сумм для ГИС ЖКХ
Нубик-Бобикorawish, а как правильно получить эти самые конечные 208145 из Typ=1 Len=2: 208,145 ?

формулируйте чётче ваши хотелки (иначе получать ответы будете как/кто ваши вопросы понял ;)

Код: plsql
1.
2.
3.
4.
select
   ascii(substrb(convert('А','UTF8'),1))
  ,ascii(substrb(convert('А','UTF8'),2))
from dual;
...
Рейтинг: 0 / 0
17.10.2016, 16:07
    #39328354
andrey_anonymous
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Расчет контрольных сумм для ГИС ЖКХ
orawish
Код: plsql
1.
2.
3.
4.
5.
6.
select
 ascii(convert('А','UTF8')) 
,ascii(convert('Б','UTF8')) 
,dump(convert('А','UTF8')) 
,dump(convert('Б','UTF8')) 
from dual;


Дело в том, что ascii ожидает параметр в кодировке БД.
Поэтому на БД с characterset AL32UTF8 оно отлично выдает код символа вида "53392".
А вот на монобайте - имеем то, что имеем.
Моя ошибка.
Вот так должно работать независимо от кодировки БД:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
with t as (select 'АаБб' s, 'AL32UTF8' tcs 
from dual union all select select 'АаБб' s, 'CL8MSWIN1251' tcs 
from dual union all select select 'АаБб' s, 'RU8PC866' tcs 
from dual
)
, t1 as (
select s, tcs
      , convert(substr(s,1,1),tcs) s1  -- конвертируем посимвольно
      , convert(substr(s,2,1),tcs) s2 
      , convert(substr(s,3,1),tcs) s3 
      , convert(substr(s,4,1),tcs) s4 
from t)
select s, tcs
      , to_number(utl_raw.cast_to_raw(s1)) n1
      , to_number(utl_raw.cast_to_raw(s2)) n2
      , to_number(utl_raw.cast_to_raw(s3)) n3
      , to_number(utl_raw.cast_to_raw(s4)) n4
from t1
;

S     TCS               N1     N2     N3     N4
----- ------------- ------ ------ ------ ------
АаБб  AL32UTF8       53392  53424  53393  53425 
АаБб  CL8MSWIN1251     192    224    193    225
АаБб  RU8PC866         128    160    129    161
...
Рейтинг: 0 / 0
17.10.2016, 16:08
    #39328357
andrey_anonymous
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Расчет контрольных сумм для ГИС ЖКХ
...endianness еще бы проверить/учесть :)
...
Рейтинг: 0 / 0
17.10.2016, 17:23
    #39328431
andrey_anonymous
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Расчет контрольных сумм для ГИС ЖКХ
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
with function f(p_elc varchar2, p_target_cs varchar2 default 'AL32UTF8') return number as
  r number := 0; c char(1 char); begin
  for i in 1..9 loop c := substr(p_elc, -i, 1) -- символы со 2 по десятый в обратном порядке
    ; r := r + i * case -- суммируем цифру либо код символа, домноженные на номер позиции справа налево
      when c in ('0','1','2','3','4','5','6','7','8','9') then to_number(c) -- цифра
      else to_number(utl_raw.cast_to_raw(convert(c,p_terget_cs)),'XXXXXXXXXXXX') -- код символа в кодировке p_target_cs
      end; end loop; return mod(r,10) -- вернем остаток от деления на 10
; end
; t as (-- тут пример исходных данных
select '40АА000177' elc
from dual union all select '?абвгодяёж'
from dual union all select '?АБВГОДЯЁЖ'
from dual
)
select elc, f(trim(elc)) X from t
;

ELC         X
---------- --
40АА000177  4
?абвгодяёж  1
?АБВГОДЯЁЖ  5
...
Рейтинг: 0 / 0
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Расчет контрольных сумм для ГИС ЖКХ / 12 сообщений из 12, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]