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

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

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

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

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

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

Я тоже так думаю.
Я давно написал UDF для етой проверки, но я стараюс избавится от ползования всех UDF.
Так как я стараюс сделать все проверки данных независимых от клиента я хочу сделат и проверка iban в базе данных
...
Рейтинг: 0 / 0
Как sql но проверит IBAN
    #39026077
Ivan_Pisarevsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anton_bgЯ давно написал UDF для етой проверкиАлгоритм? можно ссылочку на описание, блок-схему или исходник УДФ. Может там ничего страшного и нет, да и вряд ли потребуется проверять миллионы циферок.
...
Рейтинг: 0 / 0
Как sql но проверит IBAN
    #39026082
Фотография S.G.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anton_bgно я не знаю как сделать математические действия с число, которое содержит 35 цифр
Вероятно, в iban-е есть контрольное число которое вычисляется по модулю 11 или что-то подобное.
Если так, то хранить можно в varchar-е, а действия - брать посимвольно, и вычислять то что надо.
...
Рейтинг: 0 / 0
Как sql но проверит IBAN
    #39026096
Ivan_Pisarevsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
Как sql но проверит IBAN
    #39026113
Anton_bg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Алгоритм таков:

Например 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
Как sql но проверит IBAN
    #39026115
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
Как sql но проверит IBAN
    #39026117
Фотография S.G.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
Как sql но проверит IBAN
    #39026149
Anton_bg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Спасибо,
Я не знал как вычислить модул 97 с длинного числа и теперь понял
Огромное спасибо

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

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

Антон
...
Рейтинг: 0 / 0
Как sql но проверит IBAN
    #39026158
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
Как sql но проверит IBAN
    #39026167
Anton_bg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Спасибо Денис,

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

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


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

Сюда я предлагаю вам двух 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
Как sql но проверит IBAN
    #39027179
Anton_bg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Маленкая ошибка

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
Как sql но проверит IBAN
    #39027241
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anton_bg,

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

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

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

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

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


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