CLASS {{p}}iban_validator DEFINITION PUBLIC FINAL CREATE PUBLIC. PUBLIC SECTION. INTERFACES {{p}}if_iban_check. PRIVATE SECTION. TYPES: BEGIN OF ty_country, code TYPE c LENGTH 2, length TYPE i, END OF ty_country, tt_country TYPE HASHED TABLE OF ty_country WITH UNIQUE KEY code. METHODS normalize IMPORTING iv_iban TYPE string RETURNING VALUE(rv_iban) TYPE string. METHODS has_valid_format IMPORTING iv_iban TYPE string RETURNING VALUE(rv_valid) TYPE abap_bool. METHODS country_lengths RETURNING VALUE(rt_country) TYPE tt_country. METHODS remainder_97 IMPORTING iv_iban TYPE string RETURNING VALUE(rv_mod) TYPE i. ENDCLASS. CLASS {{p}}iban_validator IMPLEMENTATION. METHOD {{p}}if_iban_check~check. DATA(lv_iban) = normalize( iv_iban ). IF lv_iban IS INITIAL. rv_reason = {{p}}if_iban_check=>c_reason-empty. RETURN. ENDIF. IF has_valid_format( lv_iban ) = abap_false. rv_reason = {{p}}if_iban_check=>c_reason-chars. RETURN. ENDIF. DATA(lt_country) = country_lengths( ). ASSIGN lt_country[ code = substring( val = lv_iban len = 2 ) ] TO FIELD-SYMBOL(). IF sy-subrc <> 0. rv_reason = {{p}}if_iban_check=>c_reason-country. RETURN. ENDIF. IF strlen( lv_iban ) <> -length. rv_reason = {{p}}if_iban_check=>c_reason-length. RETURN. ENDIF. IF remainder_97( lv_iban ) <> 1. rv_reason = {{p}}if_iban_check=>c_reason-checksum. RETURN. ENDIF. rv_reason = {{p}}if_iban_check=>c_reason-ok. ENDMETHOD. METHOD normalize. rv_iban = to_upper( replace( val = iv_iban sub = ` ` with = `` occ = 0 ) ). ENDMETHOD. METHOD has_valid_format. rv_valid = xsdbool( matches( val = iv_iban pcre = `^[A-Z]{2}[0-9]{2}[A-Z0-9]*$` ) ). ENDMETHOD. METHOD country_lengths. rt_country = VALUE #( ( code = 'DE' length = 22 ) ( code = 'GB' length = 22 ) ( code = 'TR' length = 26 ) ( code = 'FR' length = 27 ) ( code = 'NL' length = 18 ) ( code = 'AT' length = 20 ) ( code = 'CH' length = 21 ) ). ENDMETHOD. METHOD remainder_97. DATA(lv_moved) = substring( val = iv_iban off = 4 ) && substring( val = iv_iban len = 4 ). DO strlen( lv_moved ) TIMES. DATA(lv_char) = substring( val = lv_moved off = sy-index - 1 len = 1 ). IF lv_char CO '0123456789'. rv_mod = ( rv_mod * 10 + CONV i( lv_char ) ) MOD 97. ELSE. rv_mod = ( rv_mod * 100 + find( val = sy-abcde sub = lv_char ) + 10 ) MOD 97. ENDIF. ENDDO. ENDMETHOD. ENDCLASS.