Гость
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Как sql но проверит IBAN / 21 сообщений из 21, страница 1 из 1
10.08.2015, 10:13
    #39026018
Anton_bg
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как sql но проверит IBAN
Здраствуйте,
Я пытаюс написать процедуру для проверки международного банковского кода IBAN вроде:

create procedure CheckIBAN(IBAN varchar(22))
RETURNS (result integer)

но я не знаю как сделать математические действия с число, которое содержит 35 цифр

Прошу помочь и извините мой плохой руский

Антон
...
Рейтинг: 0 / 0
10.08.2015, 10:24
    #39026029
Симонов Денис
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как sql но проверит IBAN
Anton_bg,

на PSQL можно конечно извратится и написать деление больших чисел, но скорее всего это эффективно работать не будет. Поэтому проще сделать либо UDF, либо контролировать на клиенте.
...
Рейтинг: 0 / 0
10.08.2015, 10:43
    #39026046
Anton_bg
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как sql но проверит IBAN
Симонов Денис,

Я тоже так думаю.
Я давно написал UDF для етой проверки, но я стараюс избавится от ползования всех UDF.
Так как я стараюс сделать все проверки данных независимых от клиента я хочу сделат и проверка iban в базе данных
...
Рейтинг: 0 / 0
10.08.2015, 11:13
    #39026077
Ivan_Pisarevsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как sql но проверит IBAN
Anton_bgЯ давно написал UDF для етой проверкиАлгоритм? можно ссылочку на описание, блок-схему или исходник УДФ. Может там ничего страшного и нет, да и вряд ли потребуется проверять миллионы циферок.
...
Рейтинг: 0 / 0
10.08.2015, 11:19
    #39026082
S.G.
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как sql но проверит IBAN
Anton_bgно я не знаю как сделать математические действия с число, которое содержит 35 цифр
Вероятно, в iban-е есть контрольное число которое вычисляется по модулю 11 или что-то подобное.
Если так, то хранить можно в varchar-е, а действия - брать посимвольно, и вычислять то что надо.
...
Рейтинг: 0 / 0
10.08.2015, 11:27
    #39026096
Ivan_Pisarevsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как sql но проверит IBAN
S.G.контрольное числоЕсл все так просто, то проблем нет. ИНН проверяем запросто
Код: sql
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.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
create or alter procedure CHECK_INN (
    INN varchar(20),
    KPP varchar(12))
returns (
    RES integer,
    WR integer)
AS
declare variable n01 integer;
declare variable n02 integer;
declare variable n03 integer;
declare variable n04 integer;
declare variable n05 integer;
declare variable n06 integer;
declare variable n07 integer;
declare variable n08 integer;
declare variable n09 integer;
declare variable n10 integer;
declare variable n11 integer;
declare variable n12 integer;
declare variable i integer;

begin
  -- результат res
  -- 1 формально корректный ИНН/КПП, правильная длина и правильная контрольная сумма
  -- 0 неправльный.
  -- результат wr (warning)
  -- 1 формально "канонический" КПП (либо все чисто для физлиц)
  -- 0 КПП формально корректный, но не совпадают первые цыфры с ИНН и хвост не "01001"

  res = 1;
  wr  = 1;

  i=1;
  while ( i <= character_length(inn) ) do
  begin
    if ( substring(inn from i for 1) not in ('0','1','2','3','4','5','6','7','8','9') ) then res=0;
    i=i+1;
  end 
  if (res=0) then begin suspend; exit; end

  if (character_length(inn)=12 and substring(inn from 1 for 2)='00') --юрики, замаскированные под физиков двумя ведущими нулями
  then
    inn = substring(inn from 3);

  if (character_length(inn)=10) --юрики
  then
  begin
    n01 = substring(inn from 1 for 1);
    n02 = substring(inn from 2 for 1);
    n03 = substring(inn from 3 for 1);
    n04 = substring(inn from 4 for 1);
    n05 = substring(inn from 5 for 1);
    n06 = substring(inn from 6 for 1);
    n07 = substring(inn from 7 for 1);
    n08 = substring(inn from 8 for 1);
    n09 = substring(inn from 9 for 1);
    --контрольная
    n10 = substring(inn from 10 for 1);

    if (n10 = mod( mod(2*n01 + 4*n02 + 10*n03 + 3*n04 + 5*n05 + 9*n06 + 4*n07 + 6*n08 + 8*n09, 11),10) )
    then
    begin
      res=1;
      if (character_length(kpp)=9) then
      begin
          while ( i <= character_length(kpp) ) do
          begin
            if ( substring(kpp from i for 1) not in ('0','1','2','3','4','5','6','7','8','9') ) then res=0;
            i=i+1;
          end 

          if ((substring (inn from 1 for 4) != substring (kpp from 1 for 4)) or (substring (kpp from 5 ) != '01001')) then wr=0;

      end
      else
      begin
        /*if ( character_length(coalesce(kpp,'')) = 0) then  res=1; else*/ res=0;
      end
    end
    else
      res = 0;
  end
  else
  if (character_length(inn)=12) --физики
  then
  begin
    n01 = substring(inn from 1 for 1);
    n02 = substring(inn from 2 for 1);
    n03 = substring(inn from 3 for 1);
    n04 = substring(inn from 4 for 1);
    n05 = substring(inn from 5 for 1);
    n06 = substring(inn from 6 for 1);
    n07 = substring(inn from 7 for 1);
    n08 = substring(inn from 8 for 1);
    n09 = substring(inn from 9 for 1);
    n10 = substring(inn from 10 for 1);

    --контрольная
    n11 = substring(inn from 11 for 1);
    n12 = substring(inn from 12 for 1);

    if (n11 = mod( mod(7*n01 + 2*n02 + 4*n03 + 10*n04 + 3*n05 + 5*n06 + 9*n07 + 4*n08 + 6*n09 + 8*n10, 11),10)
          and
        n12 = mod( mod(3*n01 + 7*n02 + 2*n03 + 4*n04 + 10*n05 + 3*n06 + 5*n07 + 9*n08 + 4*n09 + 6*n10 + 8*n11, 11),10) )

    then
    begin
      if ( character_length(coalesce(kpp,'')) = 0) then  res=1; else res=0;
    end
    else
      res = 0;
  end
  else
    res = 0;

  if (res=0) then wr=0;

  suspend;
end

...
Рейтинг: 0 / 0
10.08.2015, 11:39
    #39026113
Anton_bg
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как sql но проверит IBAN
Алгоритм таков:

Например IBAN BG33AAАА12311012345678

Шаг 1
Первые 4 символа перемещаются позади:

BG33AAАА12311012345678 -> AAАА12311012345678BG33

Шаг 2
Все буквы заменяются на цифры по следующей таблице
A= 10 G = 16 M = 22 S = 28 Y = 34
B = 11 H = 17 N = 23 T = 29 Z = 35
C = 12 I = 18 O = 24 U = 30
D = 13 J = 19 P = 25 V = 31
E = 14 K = 20 Q = 26 W = 32
F = 15 L = 21 R = 27 X = 33

AAАА12311012345678BG33 -> 1010101012311012345678111633

Шаг 3
С полученого числя вычисляетса модул 97.

Шаг 4
Если остаток при делении по модул 97 = 1 то IBAN корректный в противном случае IBAN не корректный

Етот алгоритм ползуется при проверке любого номера IBAN в ЕС
Длина номера IBAN варирует в разные страны, но максимално можетѝ быт 34 символов.
Первые два символа код державы (в примере BG - Болгария), следущие два контрольное число (в примере 33) следующие четыре BIC код банка (в примере AAAA)
...
Рейтинг: 0 / 0
10.08.2015, 11:40
    #39026115
Симонов Денис
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как sql но проверит IBAN
Anton_bg,

держи. Но это функция для тройки написана. Большой сложности переписать в ХП думаю не возникнет

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
create function long_mod97 (num varchar(35))
returns varchar(35)
as
  declare L int;
  declare n bigint;
  declare m varchar(18);
  declare nl int;
  declare xNum varchar(35);
begin
  xNum = trim(num);   -- удаляем пробелы
  m = '';
  while (xNum <> m) do
  begin
    L = char_length(xNum);  -- определяем длину числа
    nl = minvalue(18, L);  -- получаем длину первой части числа
    n = cast(substring(xNum from 1 for  nl) as bigint); -- первая часть числа
    m = cast(mod(n, 97) as varchar(18)); -- остаток от его деления на 97
    xNum = m || substring(xNum from  nl+1); -- получаем новое число
  end
  return m;
end



Ivan_Pisarevsky,

там надо число получить остаток от деления числа на 97

http://www.morfoedro.it/doc.php?lang=ru&n=219
...
Рейтинг: 0 / 0
10.08.2015, 11:43
    #39026117
S.G.
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как sql но проверит IBAN
Ivan_PisarevskyS.G.контрольное числоЕсл все так просто, то проблем нет. ИНН проверяем запросто
Оказалось, что по модую 97.

Оставлю парочку ссылок для топикстартера:
IBAN-bg
авторКонтролните цифри се изчисляват чрез MOD-97-10 съгласно стандарта ISO/IEC 7064:2003, който указва набор от системи способни да защитят низ от символи срещу грешки, които се случват при копирането на данни.

Вычисление контрольных сумм для ЕГН, ЛНЧ и IBAN

вычисление модуля большого числа - пример
авторТа, нека имаме числото 1234567890123456789012345678

Хващаш първите няколко символа, да кажем 4 и делиш по модул 97:
1234 mod 97 = 70
това 70 го умножаваш по 10 000 = 70 000. Добавяш следващата 4-ка и пак делиш:
705 678 mod 97 = 3

3 * 10 000 + 9012 => 39 012 mod 97 = 18
18 * 10 000 + 3456 => 183 456 mod 97 = 29
29 * 10 000 + 7890 => 297 890 mod 97 = 3
3 * 10 000 + 1234 => 31 234 mod 97 = 0
0 * 10 000 + 5678 => 5 678 mod 97 = 52

1234567890123456789012345678 mod 97 = 52
...
Рейтинг: 0 / 0
10.08.2015, 12:04
    #39026149
Anton_bg
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как sql но проверит IBAN
Спасибо,
Я не знал как вычислить модул 97 с длинного числа и теперь понял
Огромное спасибо

Я понял что этот форум читают и другие из Блогарии и поетому я поблагадарю и по болгарски

Благодаря
Не знаех как да сметна модул 97 от голямо число, но вече зная.
Много благодаря за помощта

Антон
...
Рейтинг: 0 / 0
10.08.2015, 12:14
    #39026158
Симонов Денис
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как sql но проверит IBAN
Anton_bg,

чуток улучшил

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
CREATE OR ALTER FUNCTION LONG_MOD97 (
    NUM VARCHAR(35))
RETURNS int
AS
declare L int;
  declare n bigint;
  declare ms varchar(2);
  declare m int;
  declare nl int;
  declare xNum varchar(35);
begin
  xNum = trim(num);   -- удаляем пробелы
  ms = '';
  while (xNum <> ms) do
  begin
    L = char_length(xNum);  -- определяем длину числа
    nl = minvalue(18, L);  -- получаем длину первой части числа
    n = cast(substring(xNum from 1 for  nl) as bigint); -- первая часть числа
    m = mod(n, 97);  -- остаток от его деления на 97
    ms = cast(m as varchar(2));
    xNum = ms || substring(xNum from  nl+1); -- получаем новое число
  end
  return m;
end
...
Рейтинг: 0 / 0
10.08.2015, 12:23
    #39026167
Anton_bg
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как sql но проверит IBAN
Спасибо Денис,

Очень нравится твой алгоритм. Так вычисление модуля 97 проходит только в 2 шага.
Cool :)

Антон
...
Рейтинг: 0 / 0
10.08.2015, 12:51
    #39026202
Симонов Денис
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как sql но проверит IBAN
Anton_bgЯ понял что этот форум читают и другие из Блогарии и поетому я поблагадарю и по болгарски


некоторые умельцы этот форум даже на английский переводят
12657258
...
Рейтинг: 0 / 0
10.08.2015, 13:02
    #39026213
S.G.
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как sql но проверит IBAN
Симонов Денис
некоторые умельцы этот форум даже на английский переводят
12657258 [offtop]
мне тут вообще как-то перевели йероглиф, не то китайский, не то японский ;)
[/offtop]
...
Рейтинг: 0 / 0
11.08.2015, 12:36
    #39026967
afgm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как sql но проверит IBAN
Anton_bgОчень нравится твой алгоритм. Так вычисление модуля 97 проходит только в 2 шага.
Чаще за 3 шага для полных 35 разрядов.
...
Рейтинг: 0 / 0
11.08.2015, 16:13
    #39027168
Anton_bg
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как sql но проверит IBAN
Здраствуйте все,

Сюда я предлагаю вам двух procedure для проверки IBAN
Они сделани благодаря вашей помощи.
Может они кому то будут полезны

Я сделал тест процедур с IBAN Греция, Испания, Болгария

Код: sql
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.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
SET TERM ^ ;

-- Процедура для вычисления модуля с длинного числа
create or alter procedure LONG_MOD (
    NUM varchar(255),
    MODULO smallint)
returns (
    RESULT integer)
as
declare variable L integer;
declare variable N bigint;
declare variable MS varchar(2);
declare variable M integer;
declare variable NL integer;
declare variable XNUM varchar(255);
begin
  Result = 0;
  if (Modulo not between 1 and 99 ) then Exit;

  xNum = trim(num);
  ms = '';
  while (xNum <> ms) do
  begin
    L = char_length(xNum);  -- Дължина на числото
    nl = minvalue(18, L);  -- Дължина на част
    n = cast(substring(xNum from 1 for  nl) as bigint); -- Част от числото
    m = mod(n, Modulo);  -- Остатък от делене по модул
    ms = cast(m as varchar(2));
    xNum = ms || substring(xNum from  nl+1); -- Ново число
  end
  Result = m;
end^

-- Процедура для проверки IBAN
create or alter procedure Check_IBAN (
    IBAN varchar(34))
returns (
    RESULT T_BOOLEAN)
as
declare variable LCHAR char(1);
declare variable LNUMBER integer;
declare variable TMPIBAN varchar(255);
declare variable LSTRING varchar(255);
declare variable I integer;
declare variable L_MOD smallint;
begin
  Result = 0;
  tmpIBAN = substring(iban from 5 for char_length(iban) - 4) || substring(iban from 1 for 4);
  i = 1;
  LString = '';
  while (i <= char_length(tmpIBAN)) do begin
    lChar = substring(tmpIBAN from i for 1);
    lNumber = ascii_val(lChar);
    IF (lNumber between 48 AND 57) THEN
      -- It's number 0 ... 9
      LString = LString || lChar;
    ELSE if (lNumber between 65 AND 90) then
      -- It's capital latin character A ... Z
      LString = LString || cast(lNumber - 55 as varchar(2));
    else if (lNumber <> 32) then
      -- Is's forbidden character
      Exit;
    i = i + 1;
  end

  execute procedure long_mod :LString, 97 returning_values :L_MOD;

  IF (l_mod = 1) THEN
    Result = 1;
  ELSE
    Result = 0;
end^

SET TERM ; ^



Антон
...
Рейтинг: 0 / 0
11.08.2015, 16:24
    #39027179
Anton_bg
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как sql но проверит IBAN
Маленкая ошибка

Anton_bgcreate or alter procedure Check_IBAN (
IBAN varchar(34))
returns (
RESULT T_BOOLEAN)


Я използовал T_BOOLEAN - ето у меня домейн

CREATE DOMAIN T_BOOLEAN AS
SMALLINT
DEFAULT 0
NOT NULL
CHECK (VALUE IN (0, 1));

Если хотите можно и так:
create or alter procedure Check_IBAN (
IBAN varchar(34))
returns (
RESULT smallint)


Антон
...
Рейтинг: 0 / 0
11.08.2015, 17:08
    #39027241
Симонов Денис
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как sql но проверит IBAN
Anton_bg,

проверку вхождения цифр и символах в нужных позициях можно с помощью регулярных выражений сделать (см. SIMILAR TO)

P.S. Пользуйся тэгом src
...
Рейтинг: 0 / 0
11.08.2015, 17:54
    #39027321
Anton_bg
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как sql но проверит IBAN
Симонов Денис,
Симонов ДенисПользуйся тэгом src

А как пользоват?
В тэг src я не вижу sql или psql. Я думал что етот тэг сделан для Oracle или для MS SQL или для других языков

Подскажи какой тэг пользоват когда хочу ставить psql?
...
Рейтинг: 0 / 0
11.08.2015, 17:58
    #39027328
S.G.
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как sql но проверит IBAN
Anton_bgПодскажи какой тэг пользоват когда хочу ставить psql?Просто тэг src.
Движок форума сам определяет что делать.
...
Рейтинг: 0 / 0
11.08.2015, 18:01
    #39027333
Anton_bg
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как sql но проверит IBAN
S.G.,

О, сейчас попробовал и понял.
Спасибо, буду иметь ввиду.
...
Рейтинг: 0 / 0
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Как sql но проверит IBAN / 21 сообщений из 21, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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