Проверка IBAN в PL / SQL

#oracle #validation #plsql #iban

#Oracle #проверка #plsql #iban

Вопрос:

Я пытаюсь найти какой-нибудь готовый к использованию код (да, я имею в виду teh codez ) для проверки номера учетной записи IBAN в PL / SQL.

Кто-нибудь знает о некоторых примерах? Я думаю, что кто-то уже должен был это реализовать…

Спасибо

Ответ №1:

Это, безусловно, не защищено авторским правом:

 declare
as_iban varchar2(34);
ln_iban number(36, 0);
begin
    as_iban := 'enter your IBAN here';

    ln_iban := to_number(substr(as_iban, 5));
    ln_iban := ln_iban * 100   (ascii(substr(as_iban, 1, 1)) - 55);
    ln_iban := ln_iban * 100   (ascii(substr(as_iban, 2, 1)) - 55);
    ln_iban := ln_iban * 100   to_number(substr(as_iban, 3, 2));
    ln_iban := ln_iban mod 97;

    if ln_iban is null or ln_iban <> 1 then 
        raise_application_error(-2e4, 'invalid IBAN: ' || as_iban);
    end if; 
end;
/
  

Комментарии:

1. Добро пожаловать в Stack Overflow! Вместо того, чтобы публиковать только блок кода, пожалуйста, объясните , почему этот код решает поставленную проблему. Без объяснения это не ответ.

Ответ №2:

Функция возвращает 1, если IBAN правильный, и 0, если он неправильный

 CREATE OR REPLACE 

    FUNCTION fn_CheckIBAN(
      pIBAN IN VARCHAR2
    ) RETURN INTEGER IS
      lResult     INTEGER;
      IBAN        VARCHAR2(256);
      IBAN_Digits VARCHAR2(256);
      l_mod       NUMBER;
      lTmp        VARCHAR2(8);
      lSCnt       INTEGER := 5;
      i           INTEGER := 1;

---

      FUNCTION fn_GetIBANDigits RETURN VARCHAR2 AS
        lChar   VARCHAR2(1);
        lNumber INTEGER;
        lString VARCHAR2(255);
      BEGIN
        FOR i IN 1..LENGTH(IBAN) LOOP
          lChar := SUBSTR(IBAN, i, 1);
          BEGIN
            lNumber := ASCII(lChar);
            IF lNumber > 47 AND lNumber < 58 THEN
              -- It's number 0 ... 9
              lString := lString || TO_CHAR(lNumber - 48);
            ELSE
              lString := lString || TO_CHAR(lNumber - 55);
            END IF;
          END;
        END LOOP;
        RETURN lString;
      END fn_GetIBANDigits;

---

     BEGIN
      IBAN := SUBSTR(pIBAN, 5) || SUBSTR(pIBAN, 1, 4);

      IBAN_Digits := fn_GetIBANDigits;

      LOOP
        lTmp := SUBSTR(IBAN_Digits, i, lSCnt);
        EXIT WHEN lTmp IS NULL;

        IF l_mod IS NULL THEN
          l_mod := MOD( TO_NUMBER(lTmp), 97);
        ELSE
          l_mod := MOD(TO_NUMBER( TO_CHAR(l_mod) || lTmp), 97);
        END IF;

        i := i   lSCnt;
      END LOOP;

      IF l_mod = 1 THEN
        lResult := 1;
      ELSE
        lResult := 0;
      END IF;

      RETURN(lResult);
    END fn_CheckIBAN;
  

Ответ №3:

Быстрый поиск в Google выдает реализацию Александра Родичевского. Это защищено авторским правом, поэтому я не уверен, законно ли его использовать. В любом случае, найдите его здесь.

Комментарии:

1. Исправьте, пожалуйста, мертвую ссылку 🙂

2. @GOXR3PLUS — вот почему StackOverflow не одобряет ответы «только для ссылок». Поскольку поток имеет принятый ответ, я просто собираюсь удалить это.

Ответ №4:

моя модификация

 CREATE OR REPLACE FUNCTION MOHF.fn_CheckIBAN(
      pIBAN IN VARCHAR2
    ) RETURN varchar2 IS
      lResult     INTEGER;
      IBAN        VARCHAR2(256);
      IBAN_Digits VARCHAR2(256);
      l_mod       NUMBER;
      lTmp        VARCHAR2(8);
      lSCnt       INTEGER := 5;
      i           INTEGER := 1;

---
FUNCTION fn_GetIBANDigits RETURN VARCHAR2 AS
        lChar   VARCHAR2(1);
        lNumber INTEGER;
        lString VARCHAR2(255);
      BEGIN
        FOR i IN 1..LENGTH(IBAN) LOOP
          lChar := SUBSTR(IBAN, i, 1);
          BEGIN
            lNumber := ASCII(lChar);
            IF lNumber > 47 AND lNumber < 58 THEN
              -- It's number 0 ... 9
              lString := lString || TO_CHAR(lNumber - 48);
            ELSE
              lString := lString || TO_CHAR(lNumber - 55);
            END IF;
          END;
        END LOOP;
        RETURN lString; 
        exception  when others then return ( null);
      END fn_GetIBANDigits;

---

     BEGIN
      IBAN := SUBSTR(pIBAN, 5) || SUBSTR(pIBAN, 1, 4);

      IBAN_Digits := fn_GetIBANDigits;

      LOOP
        lTmp := SUBSTR(IBAN_Digits, i, lSCnt);
        EXIT WHEN lTmp IS NULL;

        IF l_mod IS NULL THEN
          l_mod := MOD( TO_NUMBER(lTmp), 97);
        ELSE
          l_mod := MOD(TO_NUMBER( TO_CHAR(l_mod) || lTmp), 97);
        END IF;

        i := i   lSCnt;
      END LOOP;

      IF l_mod = 1 THEN
        lResult := 1;
      ELSE
        lResult := 0;
      END IF;

      RETURN(lResult);
      exception  when others then return ( IBAN); 
    END fn_CheckIBAN;
/
  

Комментарии:

1. Возможно, вы захотите выделить именно то, что отличает ваш ответ от предыдущего.