IBANバリデーターを作成する


8

英数字の文字列を受け入れ、ISO 13616:2007に従って検証するプログラムを記述します(関数の本体で十分です)。検証のアルゴリズムは(出典:IBANに関するWikipediaの記事http://en.wikipedia.org/wiki/International_Bank_Account_Number):

IBANの検証IBANは、それを整数に変換し、基本的なmod-97操作(ISO 7064で説明)を実行して検証されます。IBANが有効な場合、残りは1になります。IBAN検証のアルゴリズムは次のとおりです。

  • 国ごとにIBANの長さの合計が正しいことを確認してください。そうでない場合、IBANは無効です。正しいIBANの長さは次の場所にあります:http : //pastebin.com/kp4eECVk(以下にもあります)。IBAN番号の長さ順になっています。各番号の最初の2文字は国コードです。最初の2文字の後ろにある他のすべての文字(ペーストビンでは小文字ですが、実際のIBANでは大文字でもかまいません)には、任意の英数字を使用できます。
  • 最初の4文字を文字列の末尾に移動します。
  • 文字列の各文字を2桁に置き換えると、文字列が拡張され、A = 10、B = 11、...、Z = 35になります。
  • 文字列を10進整数として解釈し、その数値の剰余を97で除算して計算します

残りが1の場合、チェックディジットテストに合格し、IBANが有効である可能性があります。

例(架空の英国の銀行、ソートコード12-34-56、口座番号98765432):

- IBAN:               GB82 WEST 1234 5698 7654 32 
- Rearrange:          W E S T12345698765432 G B82
- Convert to integer: 3214282912345698765432161182    
- Compute remainder:  3214282912345698765432161182    mod 97 = 1

アルゴリズムに従って、アルゴリズムは、数値が有効な場合はtrue(または真の値)を返し、無効な場合はfalse(または偽の値)を返します。番号が実際に存在するかどうかを確認する必要はありません。有効である場合のみです。アルゴリズムは、上記のウィキペディアの記事で言及されている、承認されたさまざまなIBAN番号のそれぞれに対して機能する必要があります。このアルゴリズムは、2つの英数字の間に区切り文字がある場合とない場合の両方の数値と互換性がある必要があります。区切り文字は、ピリオド、スペース、またはダッシュのいずれかで、1つの数字にさまざまなタイプの区切り文字を含めることができます。

通常の抜け穴が適用されます。外部リソース、組み込み関数、メソッドはありません。

パズルタイプはコードゴルフです。バイトカウントで最短のコードが優先されます。プログラムの実行に必要な標準のボイラープレート(名前空間、クラス、OOPでの関数宣言など)は、バイトカウントに含まれていません。

ボーナス:有効な数値の場合、trueの代わりに適切にフォーマットされたIBAN番号(Wikipediaの各国のフォーマットに従って)を返すことができる場合、スコアが25%減少します。数値が無効な場合は、値が「無効」のリテラル文字列を返します。


ペーストビンが削除された場合のIBANの長さのコピー:

Country;Chars;IBAN Fields
Norway;15;NOkk bbbb cccc ccx
Belgium;16;BEkk bbbc cccc ccxx
Burundi;16;BIkk nnnn nnnn nnnn
Denmark;18;DKkk bbbb cccc cccc cc
Faroe Islands;18;FOkk bbbb cccc cccc cx
Finland;18;FIkk bbbb bbcc cccc cx
Greenland;18;GLkk bbbb cccc cccc cc
Netherlands;18;NLkk bbbb cccc cccc cc
Macedonia;19;MKkk bbbc cccc cccc cxx
Slovenia;19;SIkk bbss sccc cccc cxx
Austria;20;ATkk bbbb bccc cccc cccc
Bosnia and Herzegovina;20;BAkk bbbs sscc cccc ccxx
Estonia;20;EEkk bbss cccc cccc cccx
Kazakhstan;20;KZkk bbbc cccc cccc cccc
Lithuania;20;LTkk bbbb bccc cccc cccc
Luxembourg;20;LUkk bbbc cccc cccc cccc
Costa Rica;21;CRkk bbbc cccc cccc cccc c
Croatia;21;HRkk bbbb bbbc cccc cccc c
Latvia;21;LVkk bbbb cccc cccc cccc c
Liechtenstein;21;LIkk bbbb bccc cccc cccc c
Switzerland;21;CHkk bbbb bccc cccc cccc c
Bahrain;22;BHkk bbbb cccc cccc cccc cc
Bulgaria;22;BGkk bbbb ssss ddcc cccc cc
Georgia;22;GEkk bbcc cccc cccc cccc cc
Germany;22;DEkk bbbb bbbb cccc cccc cc
Ireland;22;IEkk aaaa bbbb bbcc cccc cc
Montenegro;22;MEkk bbbc cccc cccc cccc xx
Serbia;22;RSkk bbbc cccc cccc cccc xx
United Kingdom;22;GBkk bbbb ssss sscc cccc cc
Gibraltar;23;GIkk bbbb cccc cccc cccc ccc
Israel;23;ILkk bbbn nncc cccc cccc ccc
United Arab Emirates;23;AEkk bbbc cccc cccc cccc ccc
Andorra;24;ADkk bbbb ssss cccc cccc cccc
Czech Republic;24;CZkk bbbb ssss sscc cccc cccc
Moldova;24;MDkk bbcc cccc cccc cccc cccc
Pakistan;24;PKkk bbbb cccc cccc cccc cccc
Romania;24;ROkk bbbb cccc cccc cccc cccc
Saudi Arabia;24;SAkk bbcc cccc cccc cccc cccc
Slovakia;24;SKkk bbbb ssss sscc cccc cccc
Spain;24;ESkk bbbb gggg xxcc cccc cccc
Sweden;24;SEkk bbbc cccc cccc cccc cccx
Tunisia;24;TNkk bbss sccc cccc cccc cccc
Virgin Islands;24;VGkk bbbb cccc cccc cccc cccc
Algeria;24;DZkk nnnn nnnn nnnn nnnn nnnn
Portugal;25;PTkk bbbb ssss cccc cccc cccx x
Angola;25;AOkk nnnn nnnn nnnn nnnn nnnn n
Cape Verde;25;CVkk nnnn nnnn nnnn nnnn nnnn n
Mozambique;25;MZkk nnnn nnnn nnnn nnnn nnnn n
Iceland;26;ISkk bbbb sscc cccc iiii iiii ii
Turkey;26;TRkk bbbb bxcc cccc cccc cccc cc
Iran;26;IRkk nnnn nnnn nnnn nnnn nnnn nn
France;27;FRkk bbbb bggg ggcc cccc cccc cxx
Greece;27;GRkk bbbs sssc cccc cccc cccc ccc
Italy;27;ITkk xaaa aabb bbbc cccc cccc ccc
Mauritania;27;MRkk bbbb bsss sscc cccc cccc cxx
Monaco;27;MCkk bbbb bsss sscc cccc cccc cxx
San Marino;27;SMkk xaaa aabb bbbc cccc cccc ccc
Burkina Faso;27;BFkk nnnn nnnn nnnn nnnn nnnn nnn
Cameroon;27;CMkk nnnn nnnn nnnn nnnn nnnn nnn
Madagascar;27;MGkk nnnn nnnn nnnn nnnn nnnn nnn
Albania;28;ALkk bbbs sssx cccc cccc cccc cccc
Azerbaijan;28;AZkk bbbb cccc cccc cccc cccc cccc
Cyprus;28;CYkk bbbs ssss cccc cccc cccc cccc
Dominican Republic;28;DOkk bbbb cccc cccc cccc cccc cccc
Guatemala;28;GTkk bbbb cccc cccc cccc cccc cccc
Hungary;28;HUkk bbbs sssk cccc cccc cccc cccx
Lebanon;28;LBkk bbbb cccc cccc cccc cccc cccc
Poland;28;PLkk bbbs sssx cccc cccc cccc cccc
Benin;28;BJkk annn nnnn nnnn nnnn nnnn nnnn
Ivory Coast;28;CIkk annn nnnn nnnn nnnn nnnn nnnn
Mali;28;MLkk annn nnnn nnnn nnnn nnnn nnnn
Senegal;28;SNkk annn nnnn nnnn nnnn nnnn nnnn
Brazil;29;BRkk bbbb bbbb ssss sccc cccc ccct n
Palestinian;29;PSkk bbbb xxxx xxxx xccc cccc cccc c
Qatar;29;QAkk bbbb cccc cccc cccc cccc cccc c
Ukraine;29;UAkk bbbb bbcc cccc cccc cccc cccc c
Jordan;30;JOkk bbbb nnnn cccc cccc cccc cccc cc
Kuwait;30;KWkk bbbb cccc cccc cccc cccc cccc cc
Mauritius;30;MUkk bbbb bbss cccc cccc cccc cccc cc
Malta;31;MTkk bbbb ssss sccc cccc cccc cccc ccc

3
perlタグとpythonタグを追加することを提案した人には、チャレンジ内の言語タグを使用して、チャレンジを特定の言語に限定する必要があります(少なくとも、それがその意図です)。この課題はすべての言語に開かれています。そのため、編集を拒否しました。
Nzall 2014

回答:


4

J(294-73.5 = 220.5)

関数定義(f=:3 :0... ))は数えません。これはボイラープレートと考えることができるため、ブロック全体を数えると304-76 = 228のスコアが得られます。

f=:3 :0
>((1=97|1".'x',~' '-.~":48-~k-7*64<k=.3&u:4|.b)*(#b)=15+1 i.~+/"1(2{.b)&E.;.2'NO.BEBI..DKFOFIGLNL.MKSI.ATBAEEKZLTLU.CRHRLVLICH.BHBGGEDEIEMERSGB.GIILAE.ADCZMDPKROSASKESSETNVGDZ.PTAOCVMZ.ISTRIR.FRGRITMRMCSMBFCMMG.ALAZCYDOGTHULBPLBJCIMLSN.BRPSQAUA.JOKWMU.MT.'){'Invalid';1}.;' '&,&.>_4<\b=.y-.' -.'
)

テスト:

   NB. invalid numbers
   f ''
Invalid
   f 'GB82 WEST 1234 5698 7654 31'
Invalid
   f 'NL82 WEST 1234 5698 7654 32'
Invalid

   NB. different separators and formatting
   f 'GB82.WEST.1234.5698.7654.32'
GB82 WEST 1234 5698 7654 32
   f 'GB82-WEST-1234-5698-7654-32'
GB82 WEST 1234 5698 7654 32
   f 'GB82WEST12345698765432'
GB82 WEST 1234 5698 7654 32
   f 'GB82 WEST 1234 5698 7654 32'
GB82 WEST 1234 5698 7654 32
   f 'GB.82-WE ST-12.345698.76-5432'
GB82 WEST 1234 5698 7654 32

   NB. wikipedia examples
   f 'GR16 0110 1250 0000 0001 2300 695'
GR16 0110 1250 0000 0001 2300 695
   f 'CH93 0076 2011 6238 5295 7'
CH93 0076 2011 6238 5295 7
   f 'SA03 8000 0000 6080 1016 7519'
SA03 8000 0000 6080 1016 7519
   f 'GB29 NWBK 6016 1331 9268 19'
GB29 NWBK 6016 1331 9268 19

説明:

  • b=.y-.' -.':引数からセパレータを削除し、結果をに格納しbます。
  • 1}.;' '&,&.>_4<\bb4つのグループに分割し、すべてのグループの前にスペースを追加し、グループに参加して、先頭のスペースを削除します。場合y有効IBAN番号を含み、これは、正規表現(最後のグループは、おそらく未満四つの要素を有する、スペースで区切られた4つの、すなわちグループは、)です。
  • (... ){'Invalid';:文字列Invalidを要素0とし、フォーマットされたIBAN番号を要素1とする配列を作成します。IBAN番号が有効かどうかに基づいて、適切なものを選択します。

    • 長さを確認してください:
      • 'NO.BEBI.---.JOKWU.MT.':ドットで区切られた、長さごとのすべての国コードのリスト
      • +/"1(2{.b)&E.;.2:文字列をドットでグループ化し、指定された国コード(の最初の2つの要素b)を含む文字列を確認します。
      • 15+1 i.~:一致するもののインデックス15を見つけ、長さを見つけるために追加します。
      • (#b)=:の実際の長さと比較してくださいb
    • 番号を確認してください:
      • 4|.bb左に4 回転(再配置)
      • k=.3&u::各数値のASCII値を見つける
      • 48-~k-7*64<k:各文字から7を減算し、次にすべてから48を減算して、値を与える
      • 1".'x',~' '-.~"::書式を設定し、スペースを削除し、末尾に「x」を追加し(大きな数値に必要な高精度モードの場合)、数値に戻します
      • 1=97|:数値mod 97が1に等しいかどうかを確認します。
  • >:結果の文字列をunboxします

4

CJam、151.5 141.75ポイント

0000000: 6c22 202e 2d22 2d3a 512c 220f a86e 5136  l" .-"-:Q,"..nQ6
0000010: 1bff 75f6 e8e4 0b35 5dab f190 0d85 59c4  ..u....5].....Y.
0000020: 1938 4366 3d29 5eaa e879 024a 77d9 8baf  .8Cf=)^..y.Jw...
0000030: 5c16 3258 a4d2 4e6c 1a60 429f affa b8f4  \.2X..Nl.`B.....
0000040: 435d e706 457b 89a9 16b8 1d4b 08f7 9970  C]..E{.....K...p
0000050: eeb9 7467 f8e9 c935 33be 2467 3dd4 1afb  ..tg...53.$g=...
0000060: e2ec 20cc 99e4 2783 cb96 512d f9f8 7e75  .. ...'...Q-..~u
0000070: 7066 4307 2232 3536 6232 3762 2740 662b  pfC."256b27b'@f+
0000080: 2740 2f7b 5132 3c23 3126 217d 235f 573e  '@/{Q2<#1&!}#_W>
0000090: 462a 2b3d 5134 6d3c 412c 7327 5b2c 3635  F*+=Q4m<A,s'[,65
00000a0: 3e2b 6623 737e 3937 2531 3d5d 312d 2249  >+f#s~97%1=]1-"I
00000b0: 6e76 616c 6964 2251 342f 532a 3f         nvalid"Q4/S*?

上記のプログラムは189バイトの長さで、ボーナスの対象となります。

さらに26バイト(合計スコア161.25)のコストで、印刷できない文字を回避できます。

l" .-"-:Q,",YER,moTd$V6nH\-Mh/I-z(]k!uw()=j9_[C3n&As0(F;TAn$eB-r%:p+^b,1Y.j;thavi@!d,Dt7M_x-5V:#o/m_CKj-c*Imy~IjXPBCo?aM#lrN:o48u_2EKgyG@.V"33f-94b27b'@f+'@/{Q2<#1&!}#_W>F*+=Q4m<A,s'[,65>+f#s~97%1=]1-"Invalid"Q4/S*?

このバージョンはCJamインタープリターでテストできます。

実行例

$ cat gen.cjam
"l\" .-\"-:Q,"[32,15>{[
"NO"15"BE"16"BI"16"DK"18"FO"18"FI"18"GL"18"NL"18"MK"19"SI"19
"AT"20"BA"20"EE"20"KZ"20"LT"20"LU"20"CR"21"HR"21"LV"21"LI"21
"CH"21"BH"22"BG"22"GE"22"DE"22"IE"22"ME"22"RS"22"GB"22"GI"23
"IL"23"AE"23"AD"24"CZ"24"MD"24"PK"24"RO"24"SA"24"SK"24"ES"24
"SE"24"TN"24"VG"24"DZ"24"PT"25"AO"25"CV"25"MZ"25"IS"26"TR"26
"IR"26"FR"27"GR"27"IT"27"MR"27"MC"27"SM"27"BF"27"CM"27"MG"27
"AL"28"AZ"28"CY"28"DO"28"GT"28"HU"28"LB"28"PL"28"BJ"28"CI"28
"ML"28"SN"28"BR"29"PS"29"QA"29"UA"29"JO"30"KW"30"MU"30"MT"31
]2/{1=L=},0f=_!!{:+}*}fL]"@"*'@f-27b256b:c`"\\\\"/"\\"*
"256b27b'@f+'@/{Q2<#1&!}#_W>F*+=Q4m<A,s'[,65>+f#s~97%1=]1-\"Invalid\"Q4/S*?"
$ LANG=en_US cjam gen.cjam | tee >(cksum) > iban.cjam
770150303 189
$ LANG=en_US cjam iban.cjam <<< GB82WEST12345698765432; echo
GB82 WEST 1234 5698 7654 32

使い方

"…"256b27b'@f+"

文字列"…"を256を底とする数値と見なして整数に変換し、次に27を底とする数値と見なして整数の配列に変換し、@各桁にの文字コードを追加して、その過程で文字にキャストします。

その結果、次のコードが実行されます。

" Read one line from STDIN, remove allowed separators, store the result in variable
  “Q” and push its length (“,”).                                                      ";

l" .-"-:Q,

" Push the string from above.
  The correct number of characters for country code “NO” is 15.
  The correct number of characters for country codes “BE” and “BI” is 16.
  The number of characters should never be 17.
  ⋮                                                                                  ";

"NO@BEBI@@DKFOFIGLNL@MKSI@ATBAEEKZLTLU@CRHRLVLICH@BHBGGEDEIEMERSGB@"
"GIILAE@ADCZMDPKROSASKESSETNVGDZ@PTAOCVMZ@ISTRIR@FRGRITMRMCSMBFCMMG@"
"ALAZCYDOGTHULBPLBJCIMLSN@BRPSQAUA@JOKWMU@MT"++

" Split the above string at the at signs (“@”).                                       ";

'@/

" Find the index of the (first) substring such that the index of the country code 
  (“Q2<”) in the substring is even.                                                   ";

{Q2<#1&!}#

" If the country code is invalid, the index will be -1. If the index is greater than 
  -1 (“W>”), add 15 to it; if it isn't, leave -1 on the stack.                        ";

_W>F*+

" Compare the result to the length of the IBAN. Push 1 if they match and 0 otherwise. ";

=

" Push the IBAN rotated to the left by four characters.                               ";

Q4m<

" “A,s'[,65>+” pushes “0123456789ABCDEFGHIJKLMNOPQRSTUVXYZ”. For each character of 
   the IBAN, push its index in that string (-1 if not present).                       ";

A,s'[,65>+f#

" Stringify (“s”) the result, interpret the string (“~”) and compute the residue of
  the (topmost) resulting integer modulo 97.                                          ";

s97%

" Push 1 if the residue is 1; otherwise, push 0                                       ";

1=

" Wrap the entire stack in an array and remove the integer 1 from it. If the IBAN is
  valid, the array will be empty.

" If the result is falsy, the IBAN is valid; split it into substrings of length 4
  and join them using spaces (“S”). Otherwise, the IBAN is invalid; say so.           ";

"Invalid"Q4/S*?

LANG=en_US java -jar cjam-0.6.2.jar iban.cjam<<<GB82WEST12345698765432出力が無効です、何が間違っていますか(Windows8.1およびCygwinで実行中)。

@professorfish:私はWindowsコンピューターを持っていないので、ここから確認することはできませんが、まず次のことを確認してみましょう。1. iban.cjamが正常に生成されましたか?md5sum iban.cjam印刷する必要があります1960c33e31ae5646cd0400826757b3bc。2.ロケールは正しくインストールされていますか?を実行すると確認できlocale -a | grep en_USます。
Dennis

正しく生成されていません(fb620d509887f1a7298c3e5ff312401a)。locale -a|grep en_US出力en_USen_US.utf8

@professorfish:興味深い。これを試して、iban.cjamファイルを回避できますLANG=en_US cjam <(LANG=en_US cjam gen.cjam) <<< GB82WEST12345698765432。確認が簡単なASCIIのみのバージョンを回答に含めました。
デニス

2

バッシュ、 738 519 444 434 427

これが私たちを始めるための何かです。質問がサンドボックスにある間に私はそれを書きました(そして317文字、主に国コードストレージビットに保存しました)。問題があれば教えてください。

この関数は、Bashでよくあるstdinから読み取ります(質問では、「英数字の文字列を受け入れます」と言いますが、引数を介する必要はありません)。

IBANが有効な場合は0を返し、無効な場合はゼロ以外の値を返します。

IBANは、区切り文字以外の文字を含む. -A-Z0-9無効です

t=return
v=`tr -d .\ -`
[ "`tr -dc A-Z0-9<<<$v`" = $v ]||$t
((${#v}>9))||$t
r=`grep -oE "[0-9]+[A-Z]{2}*${v:0:2}"<<<15NO16BEBI18DKFIFOGLNL19MKSI20ATBAEEKZLTLU21CHCRHRLILV22BGBHDEGBGEIEMERS23AEGIIL24ADCZDZESMDPKROSASESKTNVG25AOCVMZPT26IRISTR27BFCMFRGRITMCMGMRSM28BJCICYDOGTHULBMLPLSNAZ29BRPSQAUA30JOKWMU31MT`
[ "${r:0:2}" = ${#v} ]||$t
v=${v:4:99}${v:0:4}
d=({A..Z})
for a in {10..35};{
v=${v//${d[a-10]}/$a}
}
$t `bc<<<$v%97-1`

説明

t=return # Alias return to $t
v=`tr -d .\ -` # Remove delimiters from STDIN and save to a variable $v.
# If you want the function to take the IBAN as an argument, insert <<<$1 just before the last ` in the line above
# Check that the number now contains no characters other than A-Z0-9 (i.e. if all other characters are removed, the string should remain the same because there aren't any of them)
# If not, return. By default, return uses the exit status of the previous command, which will be 1
[ "`tr -dc A-Z0-9<<<$v`" = $v ]||$t
# Check that $v is long enough to have a country code at the start, return if not
# I could have put 2 instead of 9, but the character count is the same
((${#v}>9))||$t
# give grep the country code data string, which is of the format <length1><country><country><length2><country><country><country>...
# for example, this tells you that EE has an IBAN length of 20
# grep searches for a number ([0-9]+), followed by any number including zero of country codes ([A-Z]{2}*), followed by the first two characters of the input IBAN, i.e. its country code (${v:0:2})
# -o makes grep only output the match, not the line containing it; -E enables extended regexes
# The result is saved to the variable $r
r=`grep -oE "[0-9]+[A-Z]{2}*${v:0:2}"<<<15NO16BEBI18DKFIFOGLNL19MKSI20ATBAEEKZLTLU21CHCRHRLILV22BGBHDEGBGEIEMERS23AEGIIL24ADCZDZESMDPKROSASESKTNVG25AOCVMZPT26IRISTR27BFCMFRGRITMCMGMRSM28BJCICYDOGTHULBMLPLSNAZ29BRPSQAUA30JOKWMU31MT`
# Check that the length specified by the country code, the first two chars of $r, is equal to the actual IBAN's length ${#v}. return 1 if not.
[ "${r:0:2}" = ${#v} ]||$t
v=${v:4:99}${v:0:4} # Put the first 4 chars to the back
d=({A..Z}) # Make an array of letters A to Z
# Loop for each number from 10 to 35
for a in {10..35};{
# in the IBAN, replace letters A to Z by the corresponding number from 10 to 35
v=${v//${d[a-10]}/$a}
}
# $v is now an integer
# note: I used bc here because Bash's built-in arithmetic couldn't handle big numbers
# find the remainder of dividing $v by 97, subtract 1, and return the value
# if the remainder is 1, then the IBAN is valid and 1-1=0 is returned.
$t `bc<<<$v%97-1`

ibanfn<<<'-GB82-WEST-1234 5698.7654.32    ' #returns 0, valid
ibanfn<<<'-GB82-WEST-1234 5698.7654.33    ' #returns 27, invalid, fails remainder test
ibanfn<<<'GB82 WEST 1234 5698 7654 32a'     #returns 1, invalid, contains invalid character a
ibanfn<<<'YY82 WEST 1234 5698 7654 32'      #returns 1, invalid, country code does not exist
ibanfn<<<'GB82 WEST 1234 5698 7654 3210'    #returns 1, invalid, wrong length

2

Python 3-(483-25%)362

import re
def c(i):
 i=re.sub('\W','',i);q,s='NOBEBIDKFOFIGLNLMKSIATBAEEKZLTLUCRHRLVLICHBHBGGEDEIEMERSGBGIILAEADCZMDPKROSASKESSETNVGDZPTAOCVMZISTRIRFRGRITMRMCSMBFCMMGALAZCYDOGTHULBPLBJCIMLSNBRPSQAUAJOKWMUMT',i
 for m in b" !!#####$$%%%%%%&&&&&''''''''((())))))))))))****+++,,,,,,,,,------------....///0":
  if(i[:2],len(i)+17)==(q[:2],m):
   i=i[4:]+i[:4]
   for z in range(26):i=re.sub(chr(65+z),str(z+10),i)
   return(int(i)%97==1)and re.findall('.{,4}',s)or 0
  q=q[2:]
 return 0

WT ?? -それはゴルフです!よくやった。それは少し離れたところからラインノイズのように見えます...それは補数であることに加えてj / k ;-)
G. Cito

2

Perl(356 + 2 * 75%= 268.5)

コードが非常に混乱しているため、SEの構文の強調表示も失われています。

#!perl -ln
use bignum;s/\W//g;$_=$T=uc;$q=15;/\w/?$H{$_}=$q:$q++for'NO,BEBI,,NLGLDKFOFI,SIMK,KZEEATLTLUBA,HRCHLVCRLI,RSIEGEDEBGBHGBME,GIAEIL,SASESKESCZMDTNPKADDZVGRO,PTMZCVAO,TRISIR,CMMGMRSMITFRGRBFMC,ALAZPLCIGTHUSNCYDOBJLBML,UABRQAPS,KWMUJO,MT'=~/,|../g;/../;$q=$H{$&}==y///c;/..../;$_=$'.$&;s/[A-Z]/ord($&)-55/ge;print+(Invalid,join' ',($T=~/.{1,4}/g))[1==$_%97*$q]

説明

#!perl -nl

-nstdinを1行ずつ読み取ることを意味します。-l印刷する改行を追加します

use bignum;

後のモジュロ演算で正しい値を返すために必要です。

s/\W//g;

IBANから\ w以外のすべてを削除します。

$_=$T=uc;

イバン番号を大文字に変換し、それを$ Tに保存します-後できれいに印刷するために使用されます。

$q=15;

一時変数を15に設定し、国コードからibanの長さへのマッピングを含むハッシュテーブルを作成するために使用されます。

/\w/ ? $H{$_}=$q : $q++
for 'NO,BEBI,,NLGLDKFOFI,SIMK,KZEEATLTLUBA,HRCHLVCRLI,RSIEGEDEBGBHGBME,GIAEIL,SASESKESCZMDTNPKADDZVGRO,PTMZCVAO,TRISIR,CMMGMRSMITFRGRBFMC,ALAZPLCIGTHUSNCYDOBJLBML,UABRQAPS,KWMUJO,MT' =~ /,|../g;

大きな文字列をカンマまたは2文字の国コードの配列に分割し、それを繰り返します。要素が文字で始まる場合、それは国コードです-$ qの値でハッシュに保存します。それ以外の場合、コンマは$ qをインクリメントすることを意味します。したがって、NOの値は15になり、BEとBIの値は16になります。

/../;

IBAN(国コード)の最初の2文字に一致

$q=$H{$&}==y///c;

IBANが国コードに対して正しい長さかどうかを確認し、結果を$ qに保存します

/..../;$_=$'.$&; 

最初の4文字をIBANの末尾に移動する

s/[A-Z]/ord($&)-55/ge;

A = 10で始まるすべての文字を対応する数字に置き換えます

print+(Invalid,join' ',($T=~/.{1,4}/g))[1==$_%97*$q]

「無効」またはきれいに印刷されたIBANを印刷します。 正しい長さと正しい残りのIBANの1==$_%97*$q場合1にのみ等しくなります。


1
いいね!「perl唯一」のサブコンテストで勝つ;-)混乱しますが、bashの例のように少し説明してみてください。きれいにしてください!あなたがあなたのものを説明するなら、私は私が説明します:-)(私は最初にIBAN長さの国の本当のあなたのトリックの1つを盗むかもしれませんが)。乾杯。
G. Cito 2014

2

Perl 6-354文字-(ボーナスは不明)

my $r = slurp 'ir';
my @cs = $r.comb(/(\D)+/);my @ns = $r.comb(/(\d)+/);
my %h;
for @ns Z @cs -> $n, $c {%h{$n}=[$c.comb(/\w**2/)]};
for my @ =lines() {
 my $o=$_;
 my $y=$_.substr(0,2);
 $_=s:g/\s|\-|\.//.uc.comb.rotate(4).join;
 my $l=$_.chars ; 
 $_.=trans(['A'..'Z'] => ['10'..'35']);
 next if $y !~~ %h{$l}.any;
 say $_%97==1??"$o ok"!!"Invalid";
}

IBANS.txton からの入力の読み取りSTDINとファイルからのルールの丸呑みir(ボイラープレートの場合は、ルールを合計から除外しました-ルールファイルは191文字であるため、合計は545になります。

 perl6 ibanvalidate.p6 IBANS.txt

IBANS.txt 以下のとおりであります:

GB82 WEST 1234 5698 7654 32
GB82-WEST-1234-5698-7654-32
gb82-west-1234-5698-7654-32
GB82WEST12345698765432
GB82.WEST.1234.5698.7654.32
GR16 0110 1250 0000 0001 2300 695
GB82 WEST 1234 5698 7654 31
NL82 WEST 1234 5698 7654 32
GB29 NWBK 6016 1331 9268 19
Whee perl6
CANADA 000 Banks 007 911

ノート

  • 国コードと長さを検証し、以下のように出力します
  • からの文字数: wc -m ibanvalidate.p6
  • 現在、入力のエラーチェック検証はあまり行われていません。
  • 空白はPerl6(またはPerl 5より重要)で重要なので、カウントされます。

典型的な出力:

GB82 WEST 1234 5698 7654 32 ok
GB82-WEST-1234-5698-7654-32 ok
GB82WEST12345698765432 ok
GB82.WEST.1234.5698.7654.32 ok
GR16 0110 1250 0000 0001 2300 695 ok
Invalid
GB29 NWBK 6016 1331 9268 19 ok

これは典型的なPerl6コードではありません(特に、comb友好的で影響力のあるPerl開発者がこれについて言及した行):私は初心者です。コンテストが終了したら、Perl6-ersによって提案された変更を追加/変更し、変更します。遊んでくれてありがとう:-)


国コードチェックはどこにありますか?

@professorfish ...私はそれを間違ったバージョンのperlで実行しました;-)それは確かに200以上の文字を追加します。
G. Cito 2014

1

Perl 6、311バイト、スコア233.25

{/:i^(..)<[A..Z0..9]>+$/&&'NobeBIdkfofiglNlmkSiatbaeekzltLucrhrlvliChbhbggedeiemersGbgiilAeadczmdpkrosaskessetnvgDzptaocvMzistrIrfrgritmrmcsmbfcmMgalazcydogthulbplbjcimlSnbrpsqaUajokwMumt'~~/^:i(..)*$($0)/&&.comb==$0.comb(/<:Lu>/)+15&&[.comb].rotate(4)>>.&{:36($_)}.join%97==1&&~.comb(4)||'Invalid'}o{TR/\ .-//}

オンラインでお試しください!

よく分かりません

  • 区切り文字は正確に許可されます。私はそれらすべてを単に削除します。
  • 最終的なフォーマット済み出力を大文字にするかどうか。

説明

{
  /                # Match against regex
    :i             #   ignore case
    ^              #   start of string
    (..)           #   country code (stored in $0)
    <[A..Z0..9]>+  #   alphanumeric characters
    $              #   end of string
  /
  &&
  'NobeBIdk...'    # Country code string with uppercase letter
                   # for each length increase
  ~~               # match against
  /                # regex
    :i             #   ignore case
    ^              #   start of string
    (..)*          #   series of two characters (stored in $0)
    $($0)          #   country code
  /
  &&
  .comb==          # IBAN length equals
  $0.comb(/<:Lu>/) # number of uppercase characters
  +15              # plus 15
  &&
  [.comb]          # Split IBAN into characters
  .rotate(4)       # Rotate by four
  >>.&{:36($_)}    # Convert each from base-36
  .join            # Join
  %97==1           # Modulo 97 check
  &&
  ~.comb(4)        # Add space after every four characters
  ||
  'Invalid'        # Return 'Invalid' if any of the checks failed
}
o                  # Function composition
{
  TR/\ .-//        # Remove space, dot, dash
}

0

Python3.x(539文字-25%= 404.25)

(最初に言うと、私はあなたのルールによって何がカウントされるのか少し混乱しているので、関数全体を数えました)

539の文字-を含むimportdef IBAN(i):(彼らは問題にならないように、行の先頭にタブがPythonでとにかくカウントされます)

ボーナスは、ルールに記載されているとおりに適用されます。

def IBAN(i):
    import re
    i=re.sub(r'[^\w]','',i).upper()
    k=len(i)
    z=i[:2]in re.search(r'%s([A-Z ]*)'%k,'15NO16BE BI18DK FO FI GL NL19MK SI20AT BA ES KZ LT LU21CR HR LV LI CH22BH BG GE DE IE MK RS GB23GI IL AE24MD PK RO SA SK ES SE TN VG DZ25CV MZ26IS TR IR FR GR IT MR MC SM BF CM MG28AL AZ CY DO GT HU LB PL BJ CI ML SN29BR PS QA UA30JO KW MU31MT').group(1)or None
    if int(''.join([c if c.isdigit()else str(ord(c)-55)for c in i[4:]+i[:4]]))%97!=1 or z is None:return('Invalid')
    return(' '.join([i[0+j:4+j]for j in range(0,k,4)]))

コメント付きのコード(まだ完了していません...コメントの残りの部分を書くのに疲れすぎています...明日やります)

def IBAN(i):
    import re
    # Remove all non word characters (including space) and change to uppercase
    # as0098-7*46.76A -> AS009874676A
    i=re.sub(r'[^\w]','',i).upper()
    # Get the length of it because I need it later multiple times
    k=len(i)
    #                   r'%s([A-Z ]*)'%k = Replace %s with the length of i
    #         re.search(                ,'15NO16BE BI18DK FO FI GL NL19MK SI20AT BA ES KZ LT LU21CR HR LV LI CH22BH BG GE DE IE MK RS GB23GI IL AE24MD PK RO SA SK ES SE TN VG DZ25CV MZ26IS TR IR FR GR IT MR MC SM BF CM MG28AL AZ CY DO GT HU LB PL BJ CI ML SN29BR PS QA UA30JO KW MU31MT')
    #                                    = search (with regexp) in this string (which are the lengths and countrycodes seperated by space)
    # Return the first found match (scroll to the right to see)                                                                                                                                                                                                                                .group(1)
    # i[:2]in                                                                                                                                                                                                                                                                                           or None
    # = The first two characters in the returned string (in the same order and same case)
    z=i[:2]in re.search(r'%s([A-Z ]*)'%k,'15NO16BE BI18DK FO FI GL NL19MK SI20AT BA ES KZ LT LU21CR HR LV LI CH22BH BG GE DE IE MK RS GB23GI IL AE24MD PK RO SA SK ES SE TN VG DZ25CV MZ26IS TR IR FR GR IT MR MC SM BF CM MG28AL AZ CY DO GT HU LB PL BJ CI ML SN29BR PS QA UA30JO KW MU31MT').group(1)or None
    if int(''.join([c if c.isdigit()else str(ord(c)-55)for c in i[4:]+i[:4]]))%97!=1 or z is None:return('Invalid')
    return(' '.join([i[0+j:4+j]for j in range(0,k,4)]))

0

パール(535)

まだゴルフはしていません-ボーナスの対象かどうかはわかりません;-) @professorfishタイプの説明をいくつか追加します。

#!perl -ln
$r="15NO16BEBI18DKFIFOGLNL19MKSI20ATBAEEKZLTLU21CHCRHRLILV22BGBHDEGBGEIEMERS23AEGIIL24ADCZDZESMDPKROSASESKTNVG25AOCVMZPT26IRISTR27BFCMFRGRITMCMGMRSM28BJCICYDOGTHULBMLPLSNAZ29BRPSQAUA30JOKWMU31MT";
$c{$1} = [unpack("(A2)*", $2)] while($r) =~/(\d{2})(\D{2,})/g; 
@h{("A".."Z")}=(10..35);
chomp;$o=$_;$_=uc$_;
s/[ -.]//g;
$l=y///c;
($m)=($_=~m/^.{2}/g);
($n=$_) =~s/^(....)(.*)/$2$1/dg;
$n=~s/([A-Z])/$h{$1}/g;
print $m ~~ @{$c{$l}} ? "length valid for $m":"invalid length"; 
use bignum;
print $n%97==1 ? "$o ok":"$o Invalid";

0

JavaScript(Node.js)、372バイト* .75 = 279

s=>(s=s[R="replace"](/[^A-Z0-9]/g,"")).length-14-"NO|BEBI||DKFOFIGLNL|MKSI|BATEEKZLTLU|CRCHRLVLI|GBHBGEDEIEMERS|GILAE|SADCZMDZPKROSASKESETNVG|PTAOCVMZ|ISTRIR|BFRGRITSMRMCMG|ALBJAZCYDOGTHUPLCIMLSN|BRPSQAUA|JOKWMU|MT".match(eval(`/.*${s.slice(0,2)}/i`))[0].split`|`.length||BigInt((s.slice(4)+s.slice(0,4))[R](/\w/g,x=>parseInt(x,36)))%97n-1n?"Invalid":s[R](/(.{4})/g,"$1 ")

オンラインでお試しください!

@marinusのJ回答から借用したテストケース。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.