OSDN Git Service

Some code refactoring.
authorLoRd_MuldeR <mulder2@gmx.de>
Wed, 28 Jun 2017 21:26:37 +0000 (23:26 +0200)
committerLoRd_MuldeR <mulder2@gmx.de>
Wed, 28 Jun 2017 21:26:37 +0000 (23:26 +0200)
MHashLib.vcxproj
bindings/Java/example/build.xml
bindings/Java/example/src/com/muldersoft/mhash384/example/ExampleApp.java
bindings/Java/library/build.xml
bindings/Java/library/src/com/muldersoft/mhash384/MHash384.java
include/mhash_384.h
src/utilities.h

index 2170679..5ce4297 100644 (file)
     <ClCompile Include="src\main.c" />
     <ClCompile Include="src\main++.cpp">
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
     </ClCompile>
   </ItemGroup>
index 5ab75ae..ccbec2c 100644 (file)
@@ -11,6 +11,9 @@
     </target>
     <target name="compile">
         <mkdir dir="bin"/>
+        <delete verbose="true">
+            <fileset dir="bin" includes="**/*.class"/>
+        </delete>
         <javac srcdir="src" destdir="bin" target="1.7" source="1.7" includeantruntime="false">
             <classpath>
                 <pathelement path="${libfile}"/>
index 5519eaa..7e4fdb5 100644 (file)
@@ -64,6 +64,7 @@ public class ExampleApp extends JFrame {
                                try {
                                        final List<Integer> version = MHash384.getVersion();
                                        setTitle(String.format("MHashJava384 - Example App v%d.%d.%d", version.get(0), version.get(1), version.get(2)));
+                                       MHash384.selfTest();
                                }
                                catch (UnsatisfiedLinkError err) {
                                        err.printStackTrace();
@@ -250,8 +251,11 @@ public class ExampleApp extends JFrame {
                                return digest.toString();
                        }
                        catch(Throwable err) {
-                               err.printStackTrace();
-                               JOptionPane.showMessageDialog(parent, err.getMessage(), err.getClass().getName(), JOptionPane.WARNING_MESSAGE);
+                               while(err != null) {
+                                       final String message = err.getMessage();
+                                       JOptionPane.showMessageDialog(parent, ((message != null) && (!message.isEmpty())) ? message : err.getClass().getName(), err.getClass().getName(), JOptionPane.ERROR_MESSAGE);
+                                       err = err.getCause();
+                               }
                                return null;
                        }
                }
index 6cfe1d8..7bb850d 100644 (file)
@@ -8,6 +8,9 @@
     </target>
     <target name="compile">
         <mkdir dir="bin"/>
+        <delete verbose="true">
+            <fileset dir="bin" includes="**/*.class"/>
+        </delete>
         <javac srcdir="src" destdir="bin" target="1.7" source="1.7" includeantruntime="false"/>
     </target>
     <target name="jar" depends="compile">
index 335a2b2..b0225ad 100644 (file)
@@ -39,8 +39,8 @@ public final class MHash384 {
        public static final int HASH_LENGTH = 48;
 
        private static final int LIB_VERSION_MAJOR = 1;
-       private static final int LIB_VERSION_MINOR = 0;
-       private static final int LIB_VERSION_PATCH = 1;
+       private static final int LIB_VERSION_MINOR = 1;
+       private static final int LIB_VERSION_PATCH = 0;
        
        private static final int TABLE_XOR_SIZE = 257;
        private static final int TABLE_MIX_SIZE = 997;
@@ -1305,19 +1305,6 @@ public final class MHash384 {
                /*996*/ "\u0013\u000C+-+\r$\u0019\u0012)\u0010\r\u000E\"$\u0014)\u0020&,\u001F!,-\u0019/#/,\u001F////'%-&+/-*/+,../"
        );
        
-       private static final List<String> TEST_CASES = Collections.unmodifiableList(Arrays.asList(
-               "",
-               "abc",
-               "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
-               "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
-               "Franz jagt im komplett verwahrlosten Taxi quer durch Bayern",
-               "Frank jagt im komplett verwahrlosten Taxi quer durch Bayern",
-               "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.\nDuis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.\nUt wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.\nNam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.\nDuis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis.\nAt vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, At accusam aliquyam diam diam dolore dolores duo eirmod eos erat, et nonumy sed tempor et et invidunt justo labore Stet clita ea et gubergren, kasd magna no rebum. sanctus sea sed takimata ut vero voluptua. est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat.\nConsetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus.\nLorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.\nDuis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.\nUt wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.\nNam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo.",
-               "4nfPXx\"DhcA7*'\\1;2DMhbL5f%?Yk[2]P=F*RNX*#rFo>+M,h{afxB<m_$=s4&.9~)PSYR^bs&A6JA^'>II/kH''\\%3@4ty{Ji4F|:hOU53mM]l#'^Z1rKoLU2@^g2B2MOZz:R+v5:Cp8eaRe~Z>V&S8,{]akDMsReuuarYB)_uPW]DY+f.!B=V_$H=6TavZk.p.RRF?~zdGoYJncq`+-`ojTmq:669dsEfE0wy|RS[^SzImF(cE}Ox0wLJNjw`Td,)zYgk}v_'0!fJqvV-tWsU]KP6b]Otha)0/o'QYfaIZ2I{#!Z4\"<8s#4\"M$|#;';+Oj}sPTQDNo4ILfVpNC@QIgp.W]s&BjlXm=u`:,\\\":RTh<Q!exDec>aB+`gEl=+:a.BAv8Sf5f?'s]hK&J+]\"u5@5`Lo_Y-\"=|;rAT>FR4\"D=c_aD/?Y\"HaGU^nK[O35cNo=C!y^_1\"AF8YP8,:dYjes1.!!'sNiy?e8Fj2//(vWO>N[b'u_-8pnX(d>^`^uqp9\"}m@#ejYbV**SJ]>|2m'lj,Z~#SxU%p$J1_B!r_f{wTlBW0RLS1Y:&G[l|\\_:amo&LQRJVix|@(^^6`w(ym\"#g,(f8bM=l5t0;m.aH0Mp,S9SdCw\"',*?UQk#g^L1_3:>g+Q6~'L.~2b!Qq.qa6vdMyH&JU9\\b5=QC=E\"EsBssy}G~t#R^pyKyR163bZ@G'|}/5,|#@)c!!Qm2e<ETW#=B3n9fW1B5PlX:bdC/oB}SmF[iXc;gi;1cK$eR%$|9APOTVfISe[*w*4?,k(ktt,Kd56YyY}(2z5e}Y/|FGh_Y3aH)m(e.WYmI~u9YR\"1Hs5v/j-b`T.&S#o)yiglxvhF2d]E<94;(r+BY#g::pP?Gl<di\"z\\jVX}ILca}sW9;O{iH<9kpMO']LR6%\"Jnj}Ys--,bO}$7/sO3i@knb>\"w_m7FT]O9O.qg'$7j.v<|f@p3`r!Kh\\xbZSN[i{2/?X>EF\\R&pqi&>wW!YvjQ)lD9Xt{_Y}TVPRGd>x-Po8,4nfPXx\"DhcA7*'\\1;2DMhbL5f%?Yk[2]P=F*RNX*#rFo>+M,h{afxB<m_$=s4&.9~)PSYR^bs&A6JA^'>II/kH''\\%3@4ty{Ji4F|:hOU53mM]l#'^Z1rKoLU2@^g2B2MOZz:R+v5:Cp8eaRe~Z>V&S8,{]akDMsReuuarYB)_uPW]DY+f.!B=V_$H=6TavZk.p.RRF?~zdGoYJncq`+-`ojTmq:669dsEfE0wy|RS[^SzImF(cE}Ox0wLJNjw`Td,)zYgk}v_'0!fJqvV-tWsU]KP6b]Otha)0/o'QYfaIZ2I{#!Z4\"<8s#4\"M$|#;';+Oj}sPTQDNo4ILfVpNC@QIgp.W]s&BjlXm=u`:,\\\":RTh<Q!exDec>aB+`gEl=+:a.BAv8Sf5f?'s]hK&J+]\"u5@5`Lo_Y-\"=|;rAT>FR4\"D=c_aD/?Y\"HaGU^nK[O35cNo=C!y^_1\"AF8YP8,:dYjes1.!!'sNiy?e8Fj2//(vWO>N[b'u_-8pnX(d>^`^uqp9\"}m@#ejYbV**SJ]>|2m'lj,Z~#SxU%p$J1_B!r_f{wTlBW0RLS1Y:&G[l|\\_:amo&LQRJVix|@(^^6`w(ym\"#g,(f8bM=l5t0;m.aH0Mp,S9SdCw\"',*?UQk#g^L1_3:>g+Q6~'L.~2b!Qq.qa6vdMyH&JU9\\b5=QC=E\"EsBssy}G~t#R^pyKyR163bZ@G'|}/5,|#@)c!!Qm2e<ETW#=B3n9fW1B5PlX:bdC/oB}SmF[iXc;gi;1cK$eR%$|9APOTVfISe[*w*4?,k(ktt,Kd56YyY}(2z5e}Y/|FGh_Y3aH)m(e.WYmI~u9YR\"1Hs5v/j-b`T.&S#o)yiglxvhF2d]E<94;(r+BY#g::pP?Gl<di\"z\\jVX}ILca}sW9;O{iH<9kpMO']LR6%\"Jnj}Ys--,bO}$7/sO3i@knb>\"w_m7FT]O9O.qg'$7j.v<|f@p3`r!Kh\\xbZSN[i{2/?X>EF\\R&pqi&>wW!YvjQ)lD9Xt{_Y}TVPRGd>x-Po8,",
-               "xH-5Pm^ISCqug#4f\"LM6uv/K848USL$H$G>YlzPvSE5(aa&'l@'?oKy`H;jicu=0U!OG#DLI;Ep[.Ev^h:J;Qk1@5pPqfN:q#\\K0p0]Y1lU[CP/5F8={tgMG_|`)314)9]B~Wb&xb=aBHWm(*RP%f@w]?$B|}JTw#{K$Z|$_k=rUl`1Tgvu[Q,6o([y+NJ?VWo7Ge;3s6S*Se#rF3QjPYIU7.S2d\\J!hd7.<zfUdqPmIgbBU_OK1E_-+c*!v.02>|XHsqHJ\"@[g^h*\"8<sZ?sZ_$IC'_[bIuqx0ndk#8,tJ\"jcX>kEjwfyj|\\/..D\"!OY4\\~\\zzZU^ai&'Tf>`ohw2~RH@70Nv(^g)L-K*F'N|?LZYR$-{Fz7]-<[_AS33bsgz{iV@!(B-UTq]w4+M12G1=fsSrJdXJisS)~kU|J8Za,pu*fN.EBY6*|Sr@BXlVU@cb@VEGJ>tnBx|}Nq'=*W'-qJmj$*@!qc^[t-s!<)MgKy?N|~REsh^3I\"jf:E~&xpe6h=aGq>-tEtQ/xV`)FJH?Raa.\"Yt8k'{7S8\"\"NuTR`}iqee5d3ntWj\\)gq$b$[dUOa,T4*3Zlum+l|fb-\\ZBM5U/H!St$QpgwK]lO/Bo]\\!&2#uAI(IKQ`EFsGd~i\"N>wm&K+$TSYh^x>gF!&^B+\",{[unp.>APFH3*dh_%/0Gp-Jqdh=`OFtxwx1zLaZ}?xErfrhd?@X|CEn[NAf=M;N_d'YCn3B/`<c?<|H{h1cJo/0(\"E:aG*7O4t^7IC|'Z0QD-]$pi;b3]+zUq$wk(Tt$^s3!p%4x~CnGkiq6ceDU,7{/X`kv|[J6]pqlis'N\"@SJvcp7Cah)*}`>9$BV-S&-O?mpa5I0,O&FVV|%<mt&,qw\">u5I*JY>gV;$G8QD$HLE_l;O]@tb2)XP$TT?!n6u.rZILDsrc<HW0KO@,!zHg}Yah7HI@;RNsqiToEdUj>Go4IoV>pPN\"X)W(b@Bjm.PEi\"T5TN<dee5{I;m<tI'%+xXx@*f\\m*doIM%};,ye49-@Z#C2]c3BFacDj.Bg&/3CoiJoR$s\\{Oj#Ja:.xL2faN[c(RF)Bfn+6yAzOpBj'tJ/?>rEc'Goo_LYEtJH-r.'K9i,1VmdUvUT{FPc{jOGA~w\"wq\"n9!+sO8x6KXT,fD&AoFFhmH]h~ax~%-J)h9AbA&CYam|,IL|[\\bS*f*)8kO]5:]42:m09FT5d'Gw]l)WA:!r0\\WNmTF>LJdwl&{:uyjswtADS*^s(PvQ4u8!*XDow\\'Q&bT;-p.9@<<2toyiNE\\/A+R>g4u`qyc-^>2:A]F;fA(&55VQR@5f-mzvB^-\\uny|W^i|IstzFr%pR%qTh}'Ee$R0nq0t2TUQp]w`leqN}J)])SGKDSu)_,gF`\"#RmG~NmA0lCAE/Kj0buRr$}CZZ0^gF|dzBv;PKAyAF&sk_S2'~\"b=0\"f!-`J;`fvo+k$3HvU*&hIL*A1D4nc#h0g'I]\"eI1J]\"dffZlcgu+%H'hC}5fOY:*nYbty`c6^>(V?::X}\\[3)9HE71y`mKF@c\\1LD<<|,s^+\\gf*\"n~3lb4;u>~Kn[#:uY0zjTDG=3*m9*AX3f/7]f;nT:f1z1ghXB#ZT*Rwt[v\\l=w/\\A4w#qD\"~}iF;tWi%C5Z|vC8pqv\\[VM8,!&ZC'@6_tINR2TLE[2MSGyuAJs=R'(M@1K+V\"pSw\"F=Gpzom}S2xqbl\\.sMv$*K&60W2&g^ANR_Xs~ssUx1\\y\"%L+U/)v's6BR~aGC!F,;)(S-8eTeA(}D,4!T0H\"Ip*tQYIUXUM$iJ?@(gS][n%FY24u0G:Hh7>49+~]1~l%EWHiC3\\c`x~C;P9&g?=o6OKccHIC2&?bs>\"6{0Uk$D};X~l{cOzPx)uy0SmU<`K;&romGo%av<c'-^W|{p^}4\"t+K)iG>#1uMnvY?^Ato/o1*/+(}wm:Vimc0@M-x*X#-L+ZrI&7DSl(oMqDzk7[nht\"JIu:eiubYipjD;u0t`Gz/Y^1+>?L)uDlP2ggskl,i8aaMr,'.DwR@[O@!7o`&=Rh;yA-.g9I$MNZjZ0VR\"[byEPHu82V26xigkPU{1|1;cE[Nc@w2-p+372dZ=y)U[=au':P[efVUWO+y1y4u2|#\"|R],M<l$mK0~6|<p|G8o-46[byoNMG^W%\\'+F>jvK?4g'V!V[eS#Z[`shmE5o\"j?nWMF|[[ux#P0,?O!L,oi*1d}ik5>$mGt#=</W,7~,BMVgfUbpwb-{9]:SZNLaf-zAf\"5gxtx:_R&+Ej{EdiurnI%Z#A\"qc5PK\"\"x^\\yc*J]TL&EE9z>Xwv}z>YOh]l9G[ZVl;<^Ik^8zr;*$dn$@LT}@|}=t5<3o3'^dC7dFk<f)~|ew1REb:?wUyce=2G:OGuAY-f&>wnU(}r{IA;^Tj8<odqlw_ll<;ky6L27e!H4Ig{a$7ksy{3=?AQ6(K;:*Ax-+2@#Qh[59%0LeM_'^f99*/IeqB{|LE}|P#^UFb<,?TBS$i*ghB6xnddpc/l<@6nF?CDP1<$`=;v|(@vYJ}\\Z1iB<eL/\"QaKZ&zv46pp*H#H&JC7icPB2s@5j0CqWtDCWSo7~gzl?lO=]ovB7gW`dRCc&WW@Z.Jwkyzh\\wY^Eq,@=@|0kgm)iD*x|2^EJdhTL#|eU$\\n(DpeWB[sjOVqNh@!eX:HqJcGoH+;rw6Syp{]fTUm>1Gaz:1'I6WRYN?OTl`;IDX\\D{^#3(!&744;-Ms,:BIouf'PP3@Ec<[9&1#JRceAc_9?:CiHxe63=~\"d&S)SovS75S+s\\p6JkFG}LSmK=f?tdcodC-!%d*tt`iXm'WC!fT>5)99_OUOUAByMpGMbMp<^?g+3p(_y_-tfNod.BC@E4%N0{_Yg-m,PB=_|ID4j<HcKs=>&d\"KC+fe}I03Q<,xbeu$zPL%|`q!}4C(xH+l08*<dz}Zy7<$Dg3<=peH!E{:$QQj}]Ldx(OcVuh:n2:RLPU\\i\\6:~*3X#kyEd1d^&GpX\\.mF2PR*-x;{t|YdTc*\\'#hhG8e.8qTj#wnLr#o/rK&so8,-|3[t6Ws_&riO_n6%&t9-|3HbheYP_=zkV{`VI\"/>laQ\\m^5EfGv&>0'oa}?!W(8W-e.w<Gtq1>^`_|5%^.d~hi!rx'@dmdLicn[M=\"e_s|+p=]S4d)x^M(beqVc4b/Rs@z9+~aJ\\e/oO>g+Ls+\\^/K((:'mMzuBG~|}s|WzKf.U/Z3NJLr6KD*/k7cTut`ru1],quA_c:2ezpj>i8b*6ch*,*oV3[gEs2:|2t1C7$L,+6N$t`KVv+~{cjt=8XvNCBM{,V3Bo!InB\\ONl-,~.Up}$.H(u0:!v)X~hFqI@kOZA6}Ni674G`[LlB'&\\TQX`b@&J82K093'X=][S1>ot+B(!cJG8Y~&:?B+,KsjXdAGm\\Q=*sy,U/SAwmOU`#ERSnuXJavc;|8m3]1wA2):,]K4y4ERzd)R8+NY\\rq-%S8a=0J%U#%cV::8\\a\\oT}99#9(f}}nIhvpa6+Zn>0E&+MhL:dI[x|bzIPwwv>xHZf[%I4L~v2w\"lL-@~cJRqTVhdTO00'#APkQY(Zv1/}\"qN>1b^]=!00}r:Ou%NlMD!3Y_C%AtvGs!fhR~=yrFVJ$eQVjPU\\G1r&j#1522O+LX,N2}q`?PnIRA8y;b{RKT0.-,Nu/5M~uAP~Gl92Qn<9hb`@>.-\"2CL)s7HOo}6@kQ+GY{e+\"UnhJO|Irzp@^\"x+PvRzVai>!~1sz*^`%!ay)|kB)u[Ls;@u}(W*-{gY<ARRq?X:yTX0OfO.dlb{$$94a}1^R&]WO)bAXXZ;ksL@so6T,c+WRlW'{'G8Gn[.Q}H!r<N^%wd,EhH\"dw^&UpP^AIk3Ixg/;vJSiAcUVFk|]-d5V|hjZB@BPs#F[<dpBMLa,V/nXa@O=q?/(tyALK5S!Ih\\\\w4HjHEnW-ednl`c9Xi(wC~%Rp0i_`z#=%_D4FIvk;C;MuGmj/xir\\d-.]yy\\D^!X03g}%7n_9X452YJWN<)76/S~1[s0u+%Ao5&t+q59j379Yp+y:+=/w/x2b`@#GoFSf'o:=vT&i1m\\j%j[OwVz5Dw,H1J%P,7Vtl]~8]b`~cayO4R\\\\n#S9",
-               "XJ}Zpnt1xNNhsl+\"3[9K9bdQnq|v{vk1_,~!L'*Lih=`{o$'y3S}:F\"2MJR\"M,Bw\\=VpoZ$lx+6#DJ[/eURe4=L8;HTpK%sPDf<[7;.K2t@G3z>OCZ0v=V{$;`]K!.(EYCN@dzRX,lr]HygmfFtU;zBL5z;)/Q6{KMpjz5M?A;c$k3Oxc.i!yHF>}_t4/RUc?)HKLv/Y=jZpYJ9Z!Nj53g(ePk$~4)a3|!geP?.Ipy3=\\\"iUw$N_HmXP_yEK8S@{Yq))i=~:>^,K4N5%D<'(Q:0uf&VwqaxDR1%/}n1>~,rHo\"moQmh`y>&Xf_b/w);BmIpM)9_WBxn4w$;-8hiRt%\\3/[q&<^vMq\"2bQSOmqH|o7SjX~?a/Plnn(8Qs7;%E7IR0U^s};njmmlW5f.i(1gr;#9j0f9F^~t<S8MR2&0uo<|#NJe-zmiYOh=cbtD1_<UJW?&w[%hwHoJy$M+z3?RjL55^'M/zYkO5s23&p|n2f^'QbMs!1F*d$8IOV7tPP63Xd}CGHN,hbIwf2Pw.I&*MZ/'}E{^&tS[ouat,%\\R*62_y=,K|xVA^^[=?nw1!xR7D2*N[bMqH0#ZEc5\\zzpKELCE`z[be)$1,EegU0WC|c]4fZ+C3!5l.'?:`/UMv(avO:]Q0v&}4:?PF`z4B1~o*2{HPtx|2%[LS*c<uBVTlHjhFU#&<q=Z:J7XSD&VZASUD+lg*Y|2:xb6.~-cn4A&Yl8mX-9M}G@oP?O<VesD5AKW6*GQ=.C%`03bj}Nv0-Rc)GYyaShuBJ7Rn8`S}Tg5IKTuhjxwN_o/nVC(=VHEDKQ.M#;45l.sSrChuQNtey,{V4$0Fxg2%&iO9C.P3bt@19}*2|EPIysi5yt9|3-@C`b@LmK,!#')8>s+6+`VZOrFtKsCLInbH{QFEgJ.BLXnMhqO@OQGeww#B=]+MS=qmnj~RXx0a4MtgdQ\"7A7^TtguH=,-Nrb$r'`)G_.Xep\\%~{ep;M408\\>MRdp:[C>}?)H1H'#;jA:++z]jiV,)cA.MHb[ZFSK?ROteR!z6Jvs1b0/pZ#y{ByYxAyg]Z*)o#7I=bh8`Jz?LE\"/-h7rlu)<o'9u&c-x3zDA=yltl~X5GsjxF#S)TdnyqmQVZqpLPFHU0\\Tm137~|`V\"7Qh*<d8mRCG$O^M(``R,wN=A9o[>.rC<LNKgqKorRT`ST~{\\5.2|]qj<|H@D@:|cCfXSft/_](*>xnJwp54(vz,]~_*=3e:Zr^&\\<]x?>)XC<g6?5|HE}vb-g>=f;6Vn.VDlDfMNb1pE#60={}].`?klW}\"Tu(v)U0nPqh[#U,;C&\"&iB%G%7PM9*JF3h?zXD?Yyrs_G36DJQ5Lbu[R/qYQ]8>[ePf{v-~.Sh_15.MU48:eoX<Py~$)^JQ)b;q+qTEr@57f`[xGoJZBh;Gub-<>qU>+7,G<RY-*2r3S%z)0_8!(Q1TdX%A}q_oR7e+U'|U,zQo2bi(HHX#?!FF%}LsgGK\"iX+JM:nT6jc5g0fvs3FWvP/+H/@-MoZhK\"nXoJ|mU)&Wv$1$ALW_~vI;aQm~e\\\\}yp``O!xele#OF=*@=J89g<8h_GS>DXcyg9.{*Uqt.3P34rFS'@.*z}T^KW>WkA?\"J_BOk`;zX\\w88y1o:s~~0ldTf[Mx^*>^DG4T9|:B3#q8&)IgjwpVc[_sSKxeO#0]gaA4PQO@*)'>C||ziIh|$hY@{:g3~<.$p0|S$$%5LJcvS4xURN`v~\"5$hLqRzC]wRJ4|yqB<x<1Z[U!2pst7)v^|\\9,_CS06+|LGe7FOjT$vOHOO&?n-UD'ecuS|]6S^>3D-0qJ_q{?\\9^?DF|S+n#5e6~xVY)p4?<R\\<>IS/<#ln5d{F:zf8S}][b7[tbX$RN'c+xppU`vPuN:?LPD_$dnrwsB&sEH)[-+<5D}mqb`MGLMQ&~aEqGgAMklbTt#f}r:*qkf_cE1ptxTZ?/m&\\J[QN\"30vu2IY9^$kR\"a</r'Z]*v=-'4~Kr1XSM%E<m_h|0MS!\";8@HpzMHzNC^W3}$GY)I;Zf]`A,PM)tnfZM06&M)ywHCBW_F6uan._M)'.2o^\\,/OlNgXvanc(4T)e;_b]d{O6@0xHm)f\\9RbT.hLh#-7:ty.ROvVI&sT0%qiil+qh:VD#~ElW%9lY:kz3{CFxu2E:p^`Hl2^xOB,geo%oHJ4f#vFfuuNpw/l06>Vm/:KJ'ZMWNBQ_ZgRoXJ7+\"z\"0%SLCP%<m}Qm[$<I-&oo:%hW;emi\"8/Y~0@g!^H~(GK{a~>C'9]i)Q~Vna!CsG#dN$Q_Q]Nqx{)8pz0xHH^JcY|irqpk/\".b=q1EI2*hEGY)93\"3.zEBl36&[{5Nl4+w&3EG'in\"ti@[W:*8E7D!z{|D`?|Um--1TV7CCoOP5AB#O=GD^Kl^XenqL:HI_eULs#ee)ssNN>sQ!Gv]@es0@IWwA'M}%XJ!p_g$RCj\\N\\T99EHiM~6`Ggx]K~noCP5*\\BMUP-7C@.Eqe7H8~leX94f}m;Cd@5-zSWe76426}s*QN-fmN(vG$)]bA7c]-^>P%+<fe[];914Xmvxu22a%:nPM6`(djF6:A`b+O&%t,hE%ZXg~#^dWh!MyPYbYvZjBgETs5IC-^3]wDw00PhHOc%%_l17!s6ky>'i~u_)V!M@tV[Fs7{Ls-b?|*vi;^__f8q(yVEd>3FxrOTwep/*<N|_KIS%GXIw*dtyUj<^(Q3N:SUy)ftu5v}?=Tmcnt_e-MkAMwwK(er_gG@WJoWCJg<6<om%r(~WvsQK4O[#n#(CGAxKfi'buWalivC!`85M2|\\88|4T/6,j$`/`-L@y\"yf~\\LYXU5a2)xf10;$S*JTaL4PubiG$Iv<sq^EzSI`;2FcGx~VlRV\"}N&#C|6f<B\"{8H@NbV=.Aox|t#)sB~$(I$r'j6B9`JCP[wr!%~{;Yn@\\U_#XjlBw^KkCv,.;o?5Gfo[7556-:[g2qV_>3]ao.<9lW-A!3FK?lF&@Z+_S(AxuHn6[,2TZf8rT?8#8)kInq#h@'z]~<`CP4B2{hh`+&5r5k3Y9(eC\\X0#lJ1d32R^BrQxqxlni+_H74D_|oU^Gr}pt>S_/)7__.pn0y&I-[S*Dc#(kZET1vzHGJ/T7p?:_vhl=}XK1XRyXw0$uM,6k`6R~d+--,p56~GG\\+VviT<^Uz':0B*5{P6^m<ZX=/,TRS_{dNLo.G.Wcr8a.y;-[9tW|ZP?&HbflZX\\^TyDGjk?9n}[sgn+xme`p#|G:fsaD3o[BQwWDeEDJ3Ga6?`Qh&|,J(0aY$;]QSl8\\a|lcD0wp*L?5'q}(,+SiQBWt3[[J<VA^S#_?4izlrJ68st|vGOuu8.c).=w7]/Jxdv`a7UREDEE9)x9`%;<WU,8pep#k_1[hiF=gpZ,jsb;;Pky0ZPYvf[24$+0sff|k7sratO?;X-A0Y][oRz\\rCL^_B7sIT3BL9O~Z\\t0C\"d\\FU7Q(V_0T]#k.+^SiNY95uho>{rc{-Pu\"%<$!`Ibg/w;]j$Mi<q.Lk$$Ep17zi0%mZD9X\\dWe{;oh,f[nf<0mCe>B<1,$'>1E/opGsF,fa-`/e_ZE\\U*94v[qJ.0p46=#$6QHZavH!f^t,K)Al4g5=,PbY'u4$K:mJ\"(i9Cpw$0TiLM=cVNO+()Yp`zGZ4'8H|+^R:)hXju/[G\"qfo=H*,Ep8Jc?zP0U-,%M2+-lGR/s:|eV*%C~v(?257CTDR0quCOL6g081H)O$$bqwF4^n\\e1nFvPNw:/0oC\\tu&.D+LX~N*LtPPAr0gc:QF+W2/X;q_#P20HS!HpJu:#sY~.>$t;siwyr^[3iPeo[}$!4tciN.<3,l6TGZ>Yc0DyoU<mIwW6M.WEAd|$;u+sr,_;ievqi`D-_U04^d3o.!?imF^*/U/GU?6*4\\>|6Sxi(,nAc,][@WPx:vP%Vi0'57TVHCnmg`x~Ib5^Y~_G#=Aw$[.ydp6,z\\R\"fOeCV~&&1(K2(gNXj]^[=3Pq{7<~?]>J$o8(?Ox8ZsT:p_5.@L(hBNVV<Vj?{+K\\bBY*t0>c*)1z/K*<'CE3)k}Ys'S$Tj?Wvb.fb+y|\\YSz.30DS*jJcWM7LB7&6y@^{(sCk+yYkVXfZ?;I~5$$&<-n:n*X:$:K==q7i`(W(,Jl=p.$qb2GlX-M5zX!=TUklG,\\q8-XQZ)eX#!PywvOIh'MP>^pZk3Qp89_\\]jkFIWg:sr=5@t]yzkp(Zy;!t!Ywv`j)nJOG]a?at-(-|yJ_2BRYc[L-,69?]7VBldT84<jUq+vT`dqcnHvWdmQXY/)Odg6;:Nd].R<&=@dAcrZR&|E}:~x'#n3<FRvYSh'#:%.1b:5Gv,(9#U3rZz1>22Je?8Y1D;0hN-av]ukt#Z*jti)\\x5\\j\\wVMx?eiNOY)WZ7Nd%;J~g~\"\\fI9R_bcDmh&b)JJhm%7A/,AExs><t*CkYo#*#6V$vjVox(>%|/17s.gx+zPwq1Fj|\\IO|<0=402Hk'^w>L=lj9bBZxlemVKL]8#/{T\\Y%kijgV\"Z:,EufM$4vmBo\\BXNWMs24E?,\"H\\xoJ@2f'/9b#T*@Vb7`G8oB~xh5cFtTogxNEKwg1'@!ZkP6A=XgG,u3,ug`;Vs@tT3L@q#u`_NQh5OSxKy]:*:ME%F@oY8M9N>}5Wq4'F2}'Ad]4?vECQ~kjiEwzx9<S*jAL~uv/anO]#A;<]HkxJtvgjK>Noa:/vANqg.@(2p[T}Fnm)FJ|w*/pr|Pep&2[|QQr?I11RU!;8=H/+l`IVd;(\\W_hf1+-UM=\\Jv+mA!aka[bNMP05UO|hJh=5_*ynen=\"e/jL+?D$D$\"cqa>Z04325OmYY#fsN^`|wM/mJ&\"nkT;\"0*2}Y|Aj>A*-VP$m~c,572u%IQWkdD)PBz'h|};h(@c\"g(A1,'IrpM=j&=XLKrzj\\3U{OpPr0i,^8/D9f>pw/vST,v[8nt2Dj6r/HQp8i%9a}\"PHM9).8A;}tru3\"rgZG{TviH6J:^1bCm,Qs\\_%Z6`5_}9N$!Fs(}R#6_`Kp1qE\\!fRbC%_YcM>8Z_u/)QG]:fHH8\\?v[k>uM:B=Pr%Fw'+2`D]A2S\\]s^0VkVRE!r{U$Cw@63)KEPi@OjMoOs7*R$,mUCF5w#HY#L]7TolPqZ+_G,vj[j&EfLroszQ=;xf%*imysb36M0hu219*&Uf\"z6nmgZN<'dy^Z+O!.)nXVjVt$90eWX7{rk\"Gssv{Osc?wwi3`{CJL,Rj`IvI/r2GOPoJnP`yr([s@<mn$&WPyWQrJb>Phw`<b`)v$sUdy-}$a8\"j!{_]Xz>9ijL6^C9fg[aG,K>704PCozH-2u)0'|>T-e*?_0oy@vdd,sk88XzuK*T0gu#%\\\\;dU2hlv5hJ~M{NMqH*<lw_V,UE[z=\"($i,KTPhWn0'.tf09C$%?JXhoHDrH#[~c\\zwZLrUezwGaidk/lS7N,{d=|E=?^,DgYx^F;>~yaX31:8v4]bOzC#A2bC<j_T|nf8u*1*2nLM6FS/%]3EkEcp@n]({sW':O)fe61G\";'PodS[)F7vO:TXvSg2e}W2]ompFoMJve<Y1>\\GT/Lg\\QwP]x*;c\\t)FGlk.`*&#+q\\C3{T~X<X0t&iWqWhezEN0_#CH,&V7ESf@\"=-1(*1DEK!DXVM]pQn~]#8<8#cH9ue,f4;|;8djB0`R+Q5/|EqX-hG|M2wBRC@|Xu[D!q^YrD6'7X-vMqc).Ti!6]mCof^Ez+T,G~aCh-J6Z~*rn0{ErGXvw?:jo.#%6XvfVEW#`-UXw9N0%t15=wK:sr3ogcq>XVO/8E3kXW3T7EU_Nq$qJ[i'r;y381:;WF`1\\E^6?5up#I`Jae{DOTe;!v'z,rB\"O87w0p>ztTCdKUF!+twJ&G^:6-$^`cE(h1mm2f=>O\\Ei1HGa7RJ@v,g>7',#*,1Lr!JK{&{0*}jz506;O:j)NS>EqmCXWO.(])bR!RG`}Om:!N9vym1?LIh|%}i{yh<R=$NW\\8v'\\g_7F&48ZW!r=nwc?2pN!%/?#zf2/4)i1pR!2Bf$;p>Dvc.\\~\\-IB-e~NAI7puTv<i?zjWiS0.]Cy&fbnz+ryp\"ZR,R|h!Vkn\\u8.,FolaErIi;DJr\\cv)5HHT>%B]7@uw_a_oV<,C&9p4$6x)B)Ry+/WOx?F]jeZYx-/!si02iG-*2Ry-K_=|KT]iph232\"D'*h<kW*Q-&fFOcW~Q/0LX6ej#f|(-Elf}pd6_>\\?)-]2GtVcIlE..W.$U?aNT6*R:?&qoHpS~4J.DefMz>oN>k#-^st/Z#a*46oV\\/\"XdQ7^a8TTSn31;f?SDfG]`$joE9o;/4+m_2,$HB5NO@qxg/c(B?(a)>0V2b(N$Vm>WYK(}#<T_,W\\fV`W-(&w{`}];vs<_6bKp/^P8~#R'1yo*6Pu79Es(4Rb6hcf=nodmZKwcXjw|T_^C3/CC;kL1{XRy\"|!^eo`S$qoDe\"raPjR5,>(Bi\\5xSR$gh][ck-a5r7^`(_Rh>h`WCA3zYgV+,.]kG!#R~@Mzh+c^^<\"BleMT)%E%%I/DMLkDB^kc\"X_LhXci\"J\\Sp4kl>ATGrl/|:bR1YDK\\uMfT.8*nO#Fn(L)a30zR=A$(p[sqr`J:n}lm>=?\"O-k{AG5$q,%-\"L<C=3(Z(.@}yg;*dVI3urMow#m1a$s&FQ:N.~m+5O\\aqh-GuWaK\\Br.Kh=|CUJ<O)J@S$}U+Y}EQ6t>t[fh~'X1fgd&\\s5eg)aG>sn^9o||$dBu{/EWFWTe[q1%}rD{w-|fb\\Op+f)WJ~^eY'Rpa(rpweHY(P&$vM\\m85MNX1^fXgV5*Lp|5vMC%EtTbDw|[w7>%)WT8fn_8R3'&f5UlQ/CfhSgP.%mZy5c3y.+:4n)TRa*hEAAm/*S#-W$FA#5k4<Q*U@miDS>c35=!A\\40RrKZ!DL)UCH_}@Js[cv~@g3W*mF~8aFKx6#`%Gkpy:}.9/G$[~c|<#K^h*X9iOnf9LZ>2?T\"Yu+8o502BtY[pFMyh(XDw@}?vP~tYRWB:c,JJ)c6kt>DfKOMR&t'ZC$#n(q;t(sE[mMk.nC>G\\Z4\"JrXd7i@1-Vhn5JVt7#4j2v<T6Uk+sm&Lui_mw:o8Gxz)d5='HkplV+Mp!FK,<Ju#m?gwi{b8L1r-H5_\"9Vc8pYvnYtQo=7-d\\4FV^,_[[WxaBV(9x.wEsB$;91L;ITij&)R!K!O)>Q0f&QxkJ`v&ouWX1IEc?kzbC.{%got+%Xrc=wiNT2Ldr(C;(6cKeH7XE6:(x9|ZK$`7:4`t^Bl?Sd2vl=d;GU)1YK8zku~T1RmT~K0iPQIc};+EPjv;]7|N}`2)[A11E+z7~\\/0xo$*ncPR}j@;tu\"JQtRXP:f5g!b`b?lom\"Zoc->kKup,XkeX??{:VqmY]?%/\\|7MPJ=MIB1zmQE\":'}XY14\"n7KI5n@Q*H=9qr;X[X4o/gX@N}&C01m_.v;{IVXhfy46*u%JTK&#]~zX@s3qg]g?iwXF',s'?VBbp|HP:*m)5;au8l@u4[,gZu4j~gQ=(E]Lm-kB8I{Eo$\\x<mUYd;XfRRuQgP4RM|$HX.+7{<OQJjQ6sp}qny$SA=`AH!+s5U6agLKs_$|N_2#[oq^k8h~u@Acj6w+fX*Pz*a#CHFR,Mb+Rr#-tbFe.e/HgED,8YTj&($O.uYzq72T*,H.x?4);5R.4rm/R>/3YDAbXl]i7PBpe7<E=Hj3EE,f!(N.#*G]gO7Ya*;!fAyb+Pe'ueljzr/kgvDCR7)B]ElgfEk&%77_lw8(*!wvMP^~gh/mXN<5[S{S6EU@7.F&%q|.l:<rBb/#t?>3(=DQ*/1M3g`s.v.27ba~tFDT}gDHH@}1D+9~48}k7_ZD=sZ}j42.ri/H!h=MC_Nh%gdHDF9ub6ZS;F;;Ip/]a}t\\_!.UAYf`x(?cXaym{}~kZ(&^Rc[rN^omkuNBu/qL8'U79dl4*Y_h_`*)I76?70yd@e*Li%MRs+x]&I]FtkUU7kt_jvtkj}0TJtrqh%ajL,I[J1S^RA1UpzGt\"iL/@EIp~}Kx7{nH0PDzA;']##Uh>KzE[RT1V-yl$lP?m'>~Ud'OAQ__V~XA4PYK76-eT4b_Jlvs}B~/QS\"WSooZX{,?GgF\"q]9J/FeI\\Yy\\KL66[rmwwE_.L3ayBXi66>(E&FCQaL!~+kZstp&`@j!j+>c{<DVd0|.#9;=/l/,r)b=M3w(6g/8VH}u1):O{d0GwK,qPL;tEB%a(1)\"NtV4^"
-       ));
-       
        //=========================================================================================
        // UTILITY CLASS
        //=========================================================================================
@@ -1361,40 +1348,37 @@ public final class MHash384 {
                        };
                }
                
-               public String toString() {
+               @Override
+               public final String toString() {
                        final StringBuilder sb = new StringBuilder();
                        for (final byte b : data) {
                                sb.append(String.format("%02X", b));
                        }
                        return sb.toString();
                }
+               
+               @Override
+               public final boolean equals(final Object other) {
+                       if(other instanceof ByteString) {
+                               return Arrays.equals(this.data, ((ByteString)other).data);
+                       }
+                       return false;
+               }
        }
        
        //=========================================================================================
        // INITIALIZATION
        //=========================================================================================
-       
+
        private final static List<ByteString> buildTable(final String... initializer) {
                final List<ByteString> table = new ArrayList<ByteString>(initializer.length);
                for(int i = 0; i < initializer.length; ++i) {
                        final ByteString rowData = new ByteString(initializer[i]);
-                       if(rowData.size() != HASH_LENGTH) {
-                               throw new IllegalArgumentException("Invalid initialization data!");
-                       }
                        table.add(rowData);
                }
                return Collections.unmodifiableList(table);
        }
        
-       static {
-               if(TABLE_XOR.size() != TABLE_XOR_SIZE) {
-                       throw new IllegalArgumentException("Invalid initialization data!");
-               }
-               if(TABLE_MIX.size() != TABLE_MIX_SIZE) {
-                       throw new IllegalArgumentException("Invalid initialization data!");
-               }
-       }
-       
        //=========================================================================================
        // HASH STATE
        //=========================================================================================
@@ -1474,11 +1458,64 @@ public final class MHash384 {
                return Collections.unmodifiableList(version);
        }
        
+       //=========================================================================================
+       // DEBGUGGING
+       //=========================================================================================
+       
        public final static void selfTest() {
-               for(final String testStr : TEST_CASES) {
-                       final MHash384 mhash384 = new MHash384();
-                       mhash384.update(new ByteString(testStr));
-                       System.out.println(mhash384.digest().toString());
+               final List<ByteString> TEST_VECTOR = buildTable(
+                       /*000*/ "",
+                       /*001*/ "abc",
+                       /*002*/ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+                       /*003*/ "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
+                       /*004*/ "Franz jagt im komplett verwahrlosten Taxi quer durch Bayern",
+                       /*005*/ "Frank jagt im komplett verwahrlosten Taxi quer durch Bayern",
+                       /*006*/ "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.\nDuis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.\nUt wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.\nNam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.\nDuis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis.\nAt vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, At accusam aliquyam diam diam dolore dolores duo eirmod eos erat, et nonumy sed tempor et et invidunt justo labore Stet clita ea et gubergren, kasd magna no rebum. sanctus sea sed takimata ut vero voluptua. est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat.\nConsetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus.\nLorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.\nDuis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.\nUt wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.\nNam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo.",
+                       /*007*/ "\u0092\u00AD\u00ACI\u007F\u00FA\u00B3\u000B@\u00ACgO\u009DS\u00A9\u00A6$\u00B2G\u00FA#r\u0094\u00FAu\u0088A\u00A8_M\u00DE\u00FD\u00DB\u00FD#q\u00C1\u00E2\u00CA\u00F8[\u000E\u0006K\u00BCO:\u00C0\u00A9\u00C6\u00FDl\u0018]\u00C4\u00B1,\u008A\u00AC\u00C3\u00E6%\u00BD\u00E8z\u00DF\u00CB\u00FF`\u001B\u00F0f\u00DF\u0008|\nc\u00CE,\u0011\u00D6d\u008D\u001E\u00D0W\u00CE\u001B]\u0093\u00C6\u00CBo3\u0019\u0081\u00B9\u00FC\u00B5\u00BC\u00F4\u00FBowPT\u0006\u00D7\u001A\u0087\u00EC~\u00C1\u0099U\u0097\u00FB\u00B7\u0096\u009D\u00EC\r\u00AD\u0001\u0093\u009E\u0088\u0089\u00F50\u0096?\u00E9.#\u00A8\u00F5\u00DA\u00E5G>,\u001E\"8*\u00D4\u00F7\u000E\u00A2\u00E4^\u00BB\u00CB\u00AD\u0011\u00C8zt\u008Fx\u00CBVw\u008E\u00F4\u001C\n\u00EC\u00A5c.u\u00E3R\u00B2\u00EA\u00B5S<\u0006\u00F7\u00C6\u0080\u008Ew\u00D0\u000B-\u00B5\u00F9d\u00F5\u009F\u0089\u0083\u00D9%y\"&\u00E2\u00F3\u00E6\u00D4\u00B0\u00FD\u00E7\u00BAtlY\u00BA\u009A\u0020!,%\u00DA\u0002\u00D2:\u00EE_\u0088Zu\u00F1\u001A\u00C5\u00BD\u00D5\u00CCo\u009CKr\u00BCG\u00D8@\u0089r\u0000\u00F1\u00B7\u00EF\u0097\u007F#R,\u00838\u00A3\u00FC\u00FD\u00D7r\u00C6\u0015\u00D3J\u0093F\u00BC\u00B1\u00CE7\u0014\u00FC\u000E+\u00CB\u0099\u00C74M\u00AC\u00D8H\u00A1\u00EEXCm\u00B4x\u00D00\u00E4\u0009\u00F1{:\u00E9`h\u00D9\u0006\u00F8Y\"jfG\u00D6\u0009\u008A\u0095\u0018;\u0001F\r)6{\u00A5\"\u00B4\u0005~0\u00AC\u008B\u00C2\u00D5L\u00BBcP\u000Bv\u00A16\u00EB6\u00A0w\u00D8\u00F7\u0098\u0014W\u0091\u000E\u008D\u009CB\u0095\u00E99B\u0001\u00C9\u00B8\u00DF\u0082\u0087\u00FF\u00E5\u00E6f\u0080\u000B\u0019\u00B4\u0013\u00AC\u00ECq*]5\u00C5\u00CA\u000FV\u00E6\u00A3QpX!\u00B2\u0020\u008D\u00C9\u00DE\u00CC%\u0019\u00D5\u00CF\u00A1\u00B9+h\u00BE\u00D2d2\u0094\u009B\u0002|\u00F2\u0000\u00FE=\u008B@\u00A2\u0019P\u000F\u00EEAa#\u00A8\u00C5\u00A3\u00F5\u00FC75\u001EjQB\u00AA3\u008D4\u0011\u00F8\u00B3\u00BD+t\u0099\u0016\u00FF\u00AD&\u008F\u0000\u00C5\u00F5\u001CY\"\u0002>\u00B1q\u0008C\u00BF\u00A7k\u00CD\u00033\u000ES\u009D\u00BA\u00E5(\u00CA\u0009\u00E6\u001B\u00AE\u0011v\u00A9z\u0089\u00DFH\u00DC\u0085\u00F1\u009A\u00ED\u009F\u00E1\u009F-\u00B7\u00DA!\u00BA\u00D1\u000C\u00CAg\u0005[\u00CC$[\u00EA\u00F0\u00B8l\u00C4\u00B8",
+                       /*008*/ "\u0005\u0085{\u00AA\u00C0\u00C9\u00E8b`b\u00B0\u00A0\"\u0003\u0088\u00A6\u0084C\u00AA\u008Cw\u000C\u0082\u0094]5\u0082\u0098\u0004\u001C\u00DD\u00A8\u00D4N\u0090om\u00B9\u0081\u00E2{?\u0095t$>\u009FS{\u00EF\n%Gy\u0089\\\u00B6\u00B27\u00FCOto\u007F\u00CD\u00E3s\u008B\u00F5\u00D1\u00A2<\u00BCp\u00F1A\u0084\u00F2\u00EB7\u009B\u00CB\u00C3\u00D7F.R\u00C3\u0097:\u00B6t\u00F3\u00D5\u00BBZ\u00896\u00F3\u001D\u00D5\u00A1\u000E\u00F1\u008E\u00F4\u0017&\u00CEf\u0000(\u00DE\u0017=[;\u0083{\u00D3\u00AB\u00C4\u00A1\u00EF\u008AY\u00A2\u00E2\u00BAn\u0013\u00EE\u00EA\u0083k\u00C1\u00B1\u0017\u009Ce\u001A\u00BEE\u00A7\u00B2@\u0091\u0099\u0007\u009FK_\u00BE\u00F8\u00C6~N\n\u00FF[\u00B5Z|/\u009Ew\u00EE;\u00E0\u00B5b\u0080\"\u009D-\u0013\u00CB\u00BC3\u0080\u00DD\u00AB\u0015\u00AA\u00AD\u0004:\u00AD\u008C\u00D52M02\u00F0qG'^K\u0012\u00FB\u00EF{\u00AB\u0083\u00AC\u009D\u00CD\u00ED\u00EE,%i\u0019m`\u00EF\u0018\u00B5\u00A0\u0080\u009D\u00A2\u00831\u0087\u0007SR\u00E1[L\u001E\u00FFAa4\u001C>\u001F_\u00A2X\u00D7gV#\u00B6\u00EC\u00F5\u00BC'\u00CE\u00CD\u00B4\u00B2W\u00B1;\u00EB\u00A6X\u0095\u00E0\u00B5\u00E8\u00B1\u009E\u0018?K`\u0096N\u00FBY%\u0006\u00F4\u0095\u0083\u0080\u0098]\u009FY\u009B\u0083&\u0097\u0089\u00CE\u00AC\u00BB\u00D0\\\u00957\u00DC\u00E4\u00DD/\\\"\u009Ce\u0010\u00FBa\u00A1s\u00A1j\u0089a\u0093|\u00C8n\u0080\u00B8HWHO\u0088~j\u00CE\u0090\u00F3\u00EB\u00B3\u009FP\u00F0\u000F\u00B6)`(\u00E5\u008B\u00DF\u00EA\u00CA\u00FB<\u00DD\u00AA``s\u00B3\u00AEEO\u00C9\u001D\u00B2c10;\u0085\u00BA\u008A7A\u00D6ZR\u0011\u00A2*\u00119\u00D2\u001E-\u00BF\u001AS\u008A\u0013$\u00C7\u00A3\u00DE\u00BE\u000B#r\u00CC\u0092)\u00B8+\u0092\u008F\u0008\n\u00B4\u00A6Gv)9\u00BF@\u00BCY\u009F\u00CD\u009D\u00CF5Q\u0016\u00F5D@\u00A4\u00C3\u001D\u00A8\u008Cs\u00C0\u00A1\u0012\u0084\u0015M\u00B1{JD\u00F4\u0012\u008E\u000F\u00E4L~\\\u00B2\u0092_\u00A9\u00B3q\u00DA@Px\u00C7\u0002\u001F\u0020y\u0084\u00F3\u0091\u001FGG@g+R\u00A1g\u0091\u0005\u00CA\u00B4\u00AB\u00A8i@\u00FD\u007F(\u00F6\u0017\u00B0\u00DD\u001A\u0082\u000F\u0020]\u00D29\u00A8\u009As\u00F1\u00AC\u0010\u0018<i\u0099I\u00B8\u00B2\u0090$\u00B5.\u000CW\u0093j\u001B\u000B\u009C\u00B9\u00F5Eq\u00DD\u00AF\u0094o\u00A5\u00F5\u00CF\u00B1\u00BC\u001C\u000E^Z\u000E\u00F6\u009D\u009Eq\u0011\u0099\u009F\u00A4W\u00E6m\u00D5\u0083\u0000\u00D7\u0085\u000CT\u0001\u00D4I\u001C\u00F6\u008C\u008E\u0000\u008B\u00F8HPMo\u00F1\u00EA\u00EF-d\u00D4\u00F5\u0000\u00A9\u0003\u00E6\u00CB_\u00CFl\u00D6&\u00C1\u00F4\u0097\u00CF\u00B5\u0016\u00A1b\u00DE\u00FF\u00C2\u0000\u00D0\u009A^\u00BB\u00B4v\u0086\u00FDK\u00F2)O\u000Fi\u0015}\u00AC\u00AA+\u00D1\u00BAn\u00A2\u001A\u00C1k\u009A\u0014\u0090c\u00BD\u00C416\u00BB&\u00A7i}\u0011v\u00E5?\u0005\u00C5Om\u00B0\u0012.\u00BCr\u0018\u008A\u000F\u0007\u00A1*\u00D0\u00C0\u00DE+c\u0019n\u00A8\u007F\u00C7\u009DG/\u00A6b\u00A3W\u00F07X\u009F\u0080M\u009D\u00A9/*9y\u0016j\u00CA\u00DF\"\u008F/\u00AA\u00A2ru\u0096c\u0019\u00E2\u00DF~7\u001Dh\u00F8\u00D9]\u008D@#\u007F\u00F5\u001B@3\u00CB8\u0081OJ^%<\u00F0\u0019\u00D7\u0001\u00D1!\u00F6\u00C5o\u00DA\u0017\u0083`9%f\u00F2%1X\u00A6\u00A4\u00ADFx\u00E7vW\u0019\u00CB|\u009Cm\u00E0m\u00F8\u00FD(\u0014\u0014\r\u00F0\u000C\u008F\u00D4hY\u00D2\u0096\u0015\u00BF\u00EC\u008A4\u00F7\u001A;,\u008CJ\u0098\u00167}\u0095\u0015\u00BDE\u00CB\u00F8\u00C1\u00A1\u009Ed:\u0017L\u00C4\u00D2\u00D1\u00A0\u00A4\u00BDZy\u00CBS\u00BC7\u0084\u00C8O\u009B\u00D7\u0010B=&@\u00D6\u00F2P\u0020\u0017\u008C*\u0081:\u00B5\u00D2\u008Bf\u00E5\u009F\u00CB\u00EB)\u00C8A\u00D1\u00B1\u009F\u00BAw*\u0018\u00D7\u007F\u008DF`\u00FE\u00DB\u00E4\u00C1\u00A5s\u00DD\u0088{\u0017\u00AA=X0\u009B\u00F6\u00B2fN\u00AC\u00C3\u00E3\u00A4z\u00AE\u00DF3\u00BER\u0089\u00B7\u00F9\u00B0\u0018\u00FBpc\u009A\u00C2\u00B5\u00FD\u00EF<\u008E\u0091i_\u00A8\u00E0\u00F6\u0083%\u00EF\u0016\u00AA\u00AF'\u00B5\u00D5,XW5g]\u00111\u00A3%9\r\\\u00F1\u00AC\u00D4\u00FB\u0003L\u008A\u00C0\u00FB\u00B2\u00E5\u000E\u00AD\u007F\u00C9\u00B13\u00AE\u00D9\u00EE=q\u00CB#T\u00F9\u007F\u00BF\u0002M\u00E1\u00D2\u00BCf\u00A9\\\u009D6GZbv\u00EF\u00C5\u00C80\u00BCxy\u0092b\u00A8\u00E9\u000B\u0083\u00E5\u0091B\u008F\u00FC\u00E9\u00A8l\u00AB\u00A9u\u00A1\u009Bk\u00A2\u00E5\u0087\u0096\u00BE\u0016\u0084\n\u0004)\u009F.-\u00C9\u00C8\u00DA\u00EA\u00F6\u009A%\u000F\u00F8\u00C0\u00FD\u00B5\u00D7\u0082",
+                       /*009*/ "\u00FF\u00D3\u00B0\u00A7-oh:\u000B\u0080u\u00AA\u00E0\u00E7\u001Ew2\u0081}te\u00EE\u0085\u00B5z\u00D8\u00D6S\u00CE\u009FO\u00B7\u00BD\u00D4\u00B0\u00B6{D\u00A5,.i\u00C9`\u00E3\u00AE\u00C7\u00ADf\u0004\u00DC\u001D\u00B1\u00AE\u00B2\u00AE^\u00F0x\u00CB\u0008\u00FF@\u001C64\u000C\u0010\u00E3A\u009B\u0080\u008Fb\u00BF\u00D6%\u00B7-t\u0083O$~\u00BA\u00B7\r\u0087\u009A\\r\u00E6\u00F0\u0009yQ+\u001F\u00E6J\u00C0\"\u0017Xf\u00E9\u008B\u00B2\u0092\u00E3b\u00FCsn\u00BCr\u00D5\u00CF\u0008\u0005K\u00B6\u0014<\u00913>`\u00BA\u0081\u00C3\u00FD2\u00A9\u00B7d\u00D8\u001F\u009BDc-\u001Ap\u00E1\u00F5N\u00A0\u008D<\u0020\u008CFY\u00F5\u00F4\u00E2\u00E6\u00A2\u00A7\u00E8\u0018\u00CBM\u00DBZ\u00C6\u0090\u0093\u00AC\u00DFj\u00FF\u00D1\u0000\u0096O\u00FC\u00EF\u00B7j\u00EB\u00BB\u00870O\u00FC\u0019\u00CE\u00123\u00C1\u0013\u00DE\u00DF\u00A3{\u0089\u00C2\u00A3\u00DC\u00A4\u00A9\u00BD\u0004\u0010\u0096\u00EE\u00B8w\u00FA\u0098\\B\u0001\u00F3\u00F5\u00D4\u00EF\u0018\u000E\u00B4\u000F.,\u00FC\u009A\u00D0\u00CFL\u0099\u00E1\u0020\u00F0e[\u00FE\u00AF\u00F0\u009B\u00B5\u00DF\u00D5+\u00C2=\u00B0\u00FD\u00E81<\u007F\u00A6eo\u00BA\u000E\u00D9\u00C9\u008D[\u00D1\u00EA|\u007FKR\u00ED\u0080O&\u0017\u0095\u0091k\u00B8\u0008,\u001EbO\u00D2\u00D0z\u0000u\u00A6\u0013)\u0093\u00CB\u00C4\u00C5\u00A7\u009E\u0090\u00B1|\u008C\u001CzYl\u001D]\u00FCF\u00AF\u000C\u0096\u00BA1\u0095D{\u00CB^\u00ABdB\u00F75z\u001F\u0087\u00F2\u00B3>B3(\u00CFRGG\u0013\u009A\u00A3c\u00D1\u00BDz\u00F0\u000C\u0090h\u001D\u000C\u0003\u0083\u00A9\u008E\u009Dz\\j\u001Ef\u00A9\u00F1+\u00B8\u00CE\u00A2\u00D2+\u0017!\u00B1\u0083\u0087\u00FC\u00F1\u00F3Fx\u00DC\u00D3\u0096f\u00C2\u00B4\u00D3\u0083\u0002\u00A8\u00D7\u00A5\u0095\u00DF0\u0004\u00F2\u00D1R\u008CZDbh\u00BC\u00CD\u00A7i\u00CBN\u00B4[\u0010\u0083Y\u00AC()\u0013\u0004\u00C3\u00B2z\u00C55\u00A7\u00B0\n\u00D4\u00F0\u00F0\u00EC\u00B4\u00C0\u00F2\u00D2\u00C2+\u0088\u0003\u00D5\u00E6No\u00EF\u00AD}\u00D8\u000F\u00F0l\u00B0\u00B1\u0009\u00D8\u009D\u0099\u0014\u00E3\u0000\u0005#\u00C7\u0015\u00B9\u00B1\u00B7\u00F1\u00EE\u009F\u00CE\u00049\u00B7\u00E2M\u000CZ\u0013zr\u0008!\u0011(\u00B25\u00ECz\u00E5#\u00D5f\u00D6Lz\u0082\u00FDn\u001F:\u0001\u00DC8:!{#\u00B5\u00FA\u00CC\u0005e\u008D\u00DC\u00DA\\\u00A7\n\u001A\u00A0\u0002\u00F4\u00B6\u00A024w\u00C5\u00E2\u00BB\u0010F\u00CEW\u00E3\u00A9\u000Bes\u008F\u00D5\u00A5\u0017\u0083\u0000\u00BD@\u00B1\u00EED\u00F4\u00EB([\u0096\u00A6\u00C1\u0094\u00D3\u00B6K\u00AE\u00F4r\u00F6\u00EC\u00AC\u00D4R\u009E\u00C7z\u00A8K=\u001D\u00BC\u00C0W{\u0091b\u00EEMg\u00F3\u00BA\u008D\u00BBm\u00E7H^\u00BE\u0016H\u0085lRH\u0000\u00FF\u0006\u0095\u00E1~\u00D9\u0013\u0098\u00E0m\u0096\u0013\u00B7K(;\u00AC\u00C5\n7\u0085\u00BBn\u00E5\u00E9/,\u000E\u009E\u00B7D\u00E7\u0085\u00F2[\u00FD\u00EE\u008B\u00C2\u00B80\u00E0\u0081)\u0094\u00DB3\u00FF\u00882\u0091\u00F9\u00CB\u0014\u00BC-\u0091&\u0013J\u00A2\u00E2\u00D7\u00D0\u00CA\u009F\u001F6z\u0012}\u000C\u009A\u000B\u00E6\\\u00E2\u00B7M\u00E5\u000B\u00A4>%\u00F8\u00D9\u008D\u009D\u00F4\u00E3,\u008A\u009B\u0098\u00ADk\u00F5\u000F\u00FB}\u00DA*\u00FE!\u0018v\u009A\u001AU\u00FC%\u00CA>\u00F9\u00FD\u00E4\u00B6-\u0010>Xy\u00D80\u00ED\u00DDK\u00B6\u000F\u00D5\u00D6\u00F6\u00B4\u00B17|N)\u00E6\u00F7y#t\u0001f_\u0002\u00EB\u00F2\u009FQ\u000291\u00AA\u008B\u00BC\u00DEnZm\u00AF:\u0084#4\u00F4\u0013\u009C\u0004\u00FD~l\u00E7\"\u00CC\u00B92k\u00D9\u00C2w\u00C2{\u00DF\u00E9\u00B6\u0017S\u00AF{\u00A6\u0094\u00AE99\u0000\u00EFu\u00E2M\u0015\u00F6E\u001A\u00B2\u009F\u00D6\u0082$E\u00B2\u0007\u00A7\u0000=\u0014\u0001b@\u00DD\u00D2\u00B8\u00F0\u0096\u009B\u0007\u000CI\u00F8t\u00B2\u00BF\u00E91\u00B3.\u009D/0\u00C2\u00F6\u00EDLVB\u00D4GUj\u00F49\u00C2#_X\u00BD,{\u00C5J\u00DC\u008A\u00AD@\u00E5\u0084\u00A0e\u00B3est\u009F\u00AB\u00BD\u00E6\u0009\u00A2$e\u008D\u00F6[[\u0014K\u00C0jx\u00F2\u00D6\u00F3vE\u00A0w\u00DD\u00AA\u00DB\u0013\u00F9\u009F\u000FZ\u00A5\u00A0\u00B9(H\u0095$\u0003-\u0094n\u00E1\u0005\u00F7\\#\u0082)\u0095\u00A1|\u00F2\u00E3\u00B9/\u00AC)\u0011\u00EC`\u00D1L_\u00B8\u00D2\u001E\u009D\u00ECv\u001D\u00FC_\u00C0\u00FE\u00D1P3\nB\u00D7\u0083\u00C9\u00F9IT\u00BBP\u0017lk8\u00C11\u0019\u00DB\u00FC\u00DE\u00CE\u0017\u00AD\u00B2\u00D1\u00DA\n\u0013\u00EE+\u00ED:\u00EA\u00EA\u0020\u008E\u0017\u0014\u000B\u0088\u00EE\u00B9\u00A5\u0002\u001B\u00E8l\u00F7\u00FB\u00E4\u0018r\u00E75\u0088\u00DE\u008E\u00B8V\u00FB\u00D9\u008C\u00B8\u0081\u00A79\u00AC\u00F2\u00D29\u000B\u00AF\u007F\u00B6\u00D2\u000E\u00A5\u00C7\u00A0\u00B3\u00EFoK\u00F4\u0008x\u00B2\u00A8\u0089\u00CD\u000E\u000E\u008A\u00B1\u008F\u008C\u00AC\u00E3##\u00B6\u00D1l\u0080\u00FD\u00F5Me;u\u0017\u00FC\u0081\u00A3\u0088\u0015*\u00EE\u0019\u00E0\u00FD\u00F5\u00F1\u00C2\u00C3\u00DD\u00EEz\u0008\u0012%ruBw\u008DQ[\u00D61a\u0088!s\u0086.\u00E5\u008E\u000B>\u00BEa\u00B8\u00E4\u00FD\u00FAg\u00C6Dx\u00B21\u00D9\u008B\u00BF\u00A8\u0007\u008F~\u00BEFTS$\u009A%\u00E5\u00D3_\u00C0\"\u0020\u00EA\u00C0\u0086\u00CDl\u00F8zJl\u0018\u00BD\u000F\u00CC\u00F3_\u007F\u00E0\u00BE\u00B0S\u0094_\u00E0\u0089\u0011\u0086\u0092\u00F2?\u001A\u00BD\u00E8h\u00B85;\u0091\u008F\u0085s\u0098\u00B9~\u00D1\u00C0\u00AD\u00F8Mr\u0004O\u001D\u00AD\u0082_\u0086\u00DD\u0089\u0017s8\u00F8%4\u00BAW$\u00F8\u00F3\u00E3P\u00AEA\u00D9\u0091\u00F8\u00AC\u008E\u00C4\u0087\u00F6X\u00D2\u001C1\u009B\u00C9\u000E(V\u00C9_\u0009Cs\u00A0y\u0013X\u00F2^%\u0089\u008F\u0017X\u009E\u00B3^0l\u008A\u00AB\u0081C'lS\u0082\u0008\u0019\u00B9\u00C0\u00FB\u00DA\u00F4\u00DD\u00BDUf\u008Dq\u00FFg@NS\u00B3p\"{\u0080\u0020\u008C\u0092?\u000Fs\u00AB\u00F1\u00E4Z\u00A2W=\u00DF\u00DE9\u00D0\u00E5G\u001CA\u00DAz\u0095\u000C^\u00E4\u00A3\u00844n>\u00A4\u009A\u00FD\"F\u00A9yei\u0019j\u00CE\u008A\u00E9X\u0094J\u00E1\u00D9q\u0002\u00D9\u008FF\u00A6\\YH\u001Fc\u0097\u001F\u00AF\u00FC\u0011\u00F0\u0008\u0002\u0011\u0002\u00FFp\u00A4\u00E7:\u00B9\\\u00F1p\u00CAX\u00F3\u001A\u0000\u0014\u00FA|\u00BF~\u001B\u00DE~\u00D6OX@\u00FB\u008F\u00EA\u00DC\u008B\u00EC\u00E2*\u00DD9\u0097\u0004\u00BE=\u008E\u000C\u00AD\u009BH\u00EF\u0092_v\u00E3\u000C\r@\u0020\u0008JF\u00E7e8\u00F1\u00B4C\u00E6\u0099\u0006]\u00D5M{\u00DF\u00D6Fz\u0092UV\u0008\u00E4_\u0008\u00D8\u00C5\u0094\u00A6^\u00FE;\u00EC\u00A3\u00E8T\u0090+\u00F7\u00F37%\u0090&\n\u001Cx\u00E6\u00E5\u008D\u00FFS\u0096K\u00BB\u00E4\u00DEF\u0005h|\u00BF\u0005\u0019\u00D4\u00D2\u00C6\u008E\u00AE\u00E9E1`\u00F8L\u00D1\u009A\u00F1\u00CAnna3\u00D0W\u0015\u000E\u0015j\u0014\u0006\u001D\u00CEe\u00CAEq\u00A7\u00BBz\u00DE\u00CE\u00F6\u00EAb\u00A6\u00FAT\u00C1\u00AE\u00B4w&\u0007\u00C0\u00100\u00B1\u00CC$\u00BF\u00E8E\u00C2\u00A9\u00D3Kf\u00A1\u00E3\u00F0W\u00B0\u00FE"
+               );
+               
+               final List<ByteString> TEST_RESULT = buildTable(
+                       /*000*/ "\u0086\u0003\u00847\u00A0\u0003\u0000@\u00C1\u00C9\u00C1k\u009D\u00E2\u008D\u0082\u001D\u0094Y<\u00B7\u00DD\u00A8\u00B1V\u00FF\u009A\u00E34&L.\u00885\u00B6\u0000-\u0096ez70A\u009F^C\u00F2\u0002",
+                       /*001*/ "\u0011SI\u009D\u00A6\u00B3Xz\u00C0\u00A8\u008A\u00802\u00E8\u00CE\u0016/B\u00A1\u001Ab_\u00FB\u0011\u0091i'\u00E4\u00ECvb\u00A0\u008FUR_H\u00EA\u0003c\u0093V\u0086\u00EAi\u0002\u0007\u00D3",
+                       /*002*/ "\u00A4jU\u008A\u00D1\u009A\u00AE\u00FADo3\u00FCm\u00E1<\u00FE-!4Q\n\u00DE\u00BBe\u00FD\u0016\u008E\u00FF\u00B9\u00CD\u00FC\u00F75\u009AD\u0088%\u00A0\u00C8\u008D_\u00F2\u00F2?O\u00E8\u00FA\u00FB",
+                       /*003*/ "d\u0013\u00DAe\u0091\u0094\u00FE\u00ED;\\\u0016\u00C8\u0097\u00BA\u00AA%\u00D1\u00F3n\u000Br\u00F1\u008EE\u00B9\u00F4\u00B3\u00F6\u00B9\u00F7\u00F8\u00D5\u00EC\u009C\u0016\u009E\u0085]\u008B\u00D1\u00EFK\\\u009C\u00F8\u0082\"M",
+                       /*004*/ "\u00A5!\u0092\u0002\u00F3s#a$p\u00D5\u0095\u0095T\u0017\u00D8,\u00FE\u0015\u00BA\u0081\u00AC\u00DB\u00A5\u0014\u001D\u00ED\u0004\u0007\u00BF'\u0012\u00F4>\u000E\u00D1\u0005\u001Dy\u00D2[-\u00CE\u0083\u00E9\u00D6\u0016\u00B3",
+                       /*005*/ "\u00C8\u0014\u007FW>\u0002\u00C2s\u0008~\u0001\u001C\u00B1X\u00B5\u00F3\u00D9\u00E8\u00CB\u009Ctyy\u0018~:\u00FBj\u00AB\u009F\u009C\u00E9V\u0007\u00A6'\u00A2\\\u0088\u0099\u0011\u00AB\u00FA\u001D\u0020%\u00FD\u0007",
+                       /*006*/ "\u000F\u00E9\u008E\u00B3J\u00B7\u00BD/\u00B1\u00E2y\u00E3\u00B9\u009E\u00CD6r\u00CD\n\u00B6?l[t\u00EA\u00B8\u008E\u0007\u00E6L\u00A6'\u00F7\u00DC\u00E7\"\u00E0\u00D9\u00B6`\u001Bk^\u0003C\u00D10J",
+                       /*007*/ "\u00C3\u00A0V\u0086\u00C7[\u0002\u00B4B8\u0014\u00BC\u0005\u001A\u0011Tb\u00155\u00A8\u008B\u00E1\u00D3\u00001\u0097\u001C\u008B\u00A4\u00F5^N\u00EF\u0094\u0010W\u00AD\u009C~c,\u00AA\u00A3\u00E0\u0017\u00BC\u00FE\u0097",
+                       /*008*/ "h\u00C5/\u00C23\u0020\u000E\u00CDC\u00A1\u0093\u00C1\u00FD'e\u001F\u000Fp\u0089\u0006;J\u0007L\u001A\\$\nf\u00BAx\u00F3\u00E6\u009FZ\u009EYr\u0017OR\u0017(a\u00B1\n)5",
+                       /*009*/ "8\u0013[\u001FLZ+\u00EA\u00C0\u00E5\u00F7\u0011\u0080\u00A7\u00F7\u00FA\u0003\u00C7\u00E6\u00F7\u00F1A\u00B4:\u0015\u00DA&\u0010V\u00D9\u00BB{*\u00D6\u00BA\u001B\u0005\u00DD8\u0088\u00E6K\u00A8\u00B0\u0099\u00F5Wh"
+               );
+               
+               if(TABLE_XOR.size() != TABLE_XOR_SIZE) {
+                       throw new IllegalArgumentException("Invalid initialization data!");
+               }
+               for(final ByteString row : TABLE_XOR) {
+                       if(row.size() != HASH_LENGTH) {
+                               throw new IllegalArgumentException("Invalid initialization data!");
+                       }
+               }
+               
+               if(TABLE_MIX.size() != TABLE_MIX_SIZE) {
+                       throw new IllegalArgumentException("Invalid initialization data!");
+               }
+               for(final ByteString row : TABLE_MIX) {
+                       if(row.size() != HASH_LENGTH) {
+                               throw new IllegalArgumentException("Invalid initialization data!");
+                       }
+               }
+               
+               final Iterator<ByteString> expected = TEST_RESULT.iterator();
+               for(final ByteString testInput : TEST_VECTOR) {
+                       MHash384 subject = new MHash384();
+                       subject.update(testInput);
+                       final ByteString result = subject.digest();
+                       System.out.println(result);
+                       if(!result.equals(expected.next())) {
+                               throw new IllegalArgumentException("Test vector did NOT compare equal");
+                       }
                }
        }
 }
index 203af8b..2a7acc6 100644 (file)
@@ -63,29 +63,19 @@ namespace internals {
 /* ======================================================================== */
 
 /*Version*/
-#ifdef __cplusplus
 static const uint16_t MHASH_384_VERSION_MAJOR = UINT32_C(1);
-static const uint16_t MHASH_384_VERSION_MINOR = UINT32_C(0);
-static const uint16_t MHASH_384_VERSION_PATCH = UINT32_C(1);
-#else
-#define MHASH_384_VERSION_MAJOR UINT32_C(1)
-#define MHASH_384_VERSION_MINOR UINT32_C(0)
-#define MHASH_384_VERSION_PATCH UINT32_C(1)
-#endif
+static const uint16_t MHASH_384_VERSION_MINOR = UINT32_C(1);
+static const uint16_t MHASH_384_VERSION_PATCH = UINT32_C(0);
 
-/*Hash and table size definitions*/
+/*Hash length definition*/
 #ifdef __cplusplus
 static const uint16_t MHASH_384_LEN = UINT16_C(48);
-static const uint16_t MHASH_384_TSIZE_XOR = UINT16_C(UINT8_MAX + 2U);
-static const uint16_t MHASH_384_TSIZE_MIX = UINT16_C(997);
 #else
 #define MHASH_384_LEN UINT16_C(48)
-#define MHASH_384_TSIZE_XOR UINT16_C(UINT8_MAX+2U)
-#define MHASH_384_TSIZE_MIX UINT16_C(997)
 #endif
 
 /*Table XOR: 257x48 matrix containing pre-computed 384-bit words with HamD(a,b) >= 180 for each possible pair (a,b) with a != b*/
-static const uint8_t MHASH_384_TABLE_XOR[MHASH_384_TSIZE_XOR][MHASH_384_LEN] =
+static const uint8_t MHASH_384_TABLE_XOR[][MHASH_384_LEN] =
 {
        { 0x41,0xA8,0xBF,0xAF,0xD3,0xAA,0xDA,0x1F,0x86,0x12,0xC9,0xEE,0x67,0xA2,0xE7,0x9E,0xEE,0x7C,0x12,0xEE,0x9E,0xD9,0xAA,0x4A,0x9F,0x78,0xE2,0x88,0x05,0x5E,0x46,0x51,0x8C,0xBB,0xAF,0xFA,0xE5,0x6E,0x69,0x7C,0xAF,0x18,0x95,0x76,0xBB,0x07,0xB2,0x9B }, /*00*/
        { 0x56,0x32,0x92,0x79,0x33,0x26,0x36,0x7D,0xDF,0x6F,0x00,0x18,0xAC,0xC7,0x56,0xC3,0xF8,0xF3,0xAE,0x1F,0xFA,0x61,0x78,0x9F,0x8F,0x4B,0xC6,0x31,0x18,0x69,0x40,0xA1,0x09,0xA3,0xA9,0x8E,0x38,0x0A,0x28,0xE0,0x41,0xE5,0xBA,0x67,0xD7,0xA2,0xCE,0xF0 }, /*01*/
@@ -347,7 +337,7 @@ static const uint8_t MHASH_384_TABLE_XOR[MHASH_384_TSIZE_XOR][MHASH_384_LEN] =
 };
 
 /*Table MIX: 256x48 matrix containg pre-computed Fisher\96Yates permutations indices*/
-uint8_t MHASH_384_TABLE_MIX[MHASH_384_TSIZE_MIX][MHASH_384_LEN] =
+uint8_t MHASH_384_TABLE_MIX[][MHASH_384_LEN] =
 {
        { 0x06,0x17,0x05,0x21,0x10,0x2A,0x12,0x0F,0x13,0x12,0x1B,0x23,0x1E,0x2C,0x1B,0x2E,0x23,0x25,0x18,0x2F,0x29,0x23,0x2C,0x1F,0x2E,0x1A,0x2E,0x20,0x23,0x26,0x2F,0x22,0x2D,0x21,0x2E,0x25,0x2F,0x2C,0x27,0x2B,0x2F,0x2B,0x2C,0x2C,0x2E,0x2F,0x2F,0x2F }, /*000*/
        { 0x29,0x16,0x27,0x27,0x2C,0x08,0x2E,0x0C,0x08,0x18,0x20,0x28,0x2D,0x0E,0x15,0x11,0x15,0x25,0x15,0x17,0x26,0x1D,0x29,0x1C,0x2A,0x28,0x2A,0x20,0x23,0x2E,0x2D,0x2C,0x2B,0x2D,0x2A,0x24,0x2D,0x2F,0x2A,0x28,0x2F,0x29,0x2A,0x2F,0x2D,0x2F,0x2E,0x2F }, /*001*/
@@ -1348,6 +1338,10 @@ uint8_t MHASH_384_TABLE_MIX[MHASH_384_TSIZE_MIX][MHASH_384_LEN] =
        { 0x13,0x0C,0x2B,0x2D,0x2B,0x0D,0x24,0x19,0x12,0x29,0x10,0x0D,0x0E,0x22,0x24,0x14,0x29,0x20,0x26,0x2C,0x1F,0x21,0x2C,0x2D,0x19,0x2F,0x23,0x2F,0x2C,0x1F,0x2F,0x2F,0x2F,0x2F,0x27,0x25,0x2D,0x26,0x2B,0x2F,0x2D,0x2A,0x2F,0x2B,0x2C,0x2E,0x2E,0x2F }  /*996*/
 };
 
+/*Table size constants*/
+static const uint32_t MHASH_384_TSIZE_XOR = (uint32_t)(sizeof(MHASH_384_TABLE_XOR) / sizeof(MHASH_384_TABLE_XOR[0]));
+static const uint32_t MHASH_384_TSIZE_MIX = (uint32_t)(sizeof(MHASH_384_TABLE_MIX) / sizeof(MHASH_384_TABLE_MIX[0]));
+
 /* ======================================================================== */
 /* TYPES                                                                    */
 /* ======================================================================== */
@@ -1417,6 +1411,8 @@ private:
        internals::mhash_384_t m_context;
 
 public:
+       static const uint16_t HASH_LEN = internals::MHASH_384_LEN;
+
        MHash384(void)
        {
                internals::mhash_384_initialize(&m_context);
@@ -1442,7 +1438,7 @@ public:
 
        inline std::vector<uint8_t> finalize(void) const
        {
-               std::vector<uint8_t> result(MHASH_384_LEN);
+               std::vector<uint8_t> result(internals::MHASH_384_LEN);
                internals::mhash_384_finalize(&m_context, result.data());
                return result;
        }
@@ -1452,6 +1448,13 @@ public:
        {
                internals::mhash_384_finalize(&m_context, output);
        }
+
+       inline static void version(uint16_t &major, uint16_t &minor, uint16_t &patch)
+       {
+               major = internals::MHASH_384_VERSION_MAJOR;
+               minor = internals::MHASH_384_VERSION_MINOR;
+               patch = internals::MHASH_384_VERSION_PATCH;
+       }
 };
 #endif
 
index 3780456..5739b6d 100644 (file)
 #include <sys/stat.h>
 #include <signal.h>
 
+/*Hash size*/
+#ifdef __cplusplus
+static const uint16_t HASH_LENGTH = mhash_384::MHash384::HASH_LEN;
+#else
+static const uint16_t HASH_LENGTH = MHASH_384_LEN;
+#endif
+
 /*Parameters*/
 typedef struct param_t
 {
@@ -44,10 +51,34 @@ typedef struct param_t
 }
 param_t;
 
+/*Version*/
+typedef struct version_t
+{
+       uint16_t major;
+       uint16_t minor;
+       uint16_t patch;
+}
+version_t;
+
+/*Get version*/
+static version_t get_version(void)
+{
+       version_t version_info;
+#ifdef __cplusplus
+       mhash_384::MHash384::version(version_info.major, version_info.minor, version_info.patch);
+#else
+       version_info.major = MHASH_384_VERSION_MAJOR;
+       version_info.minor = MHASH_384_VERSION_MINOR;
+       version_info.patch = MHASH_384_VERSION_PATCH;
+#endif
+       return version_info;
+}
+
 /*The logo*/
 static void print_logo(void)
 {
-       fprintf(stderr, "\nMHash384 v%u.%u.%u, simple fast portable header-only hashing library [%s]\n", MHASH_384_VERSION_MAJOR, MHASH_384_VERSION_MINOR, MHASH_384_VERSION_PATCH, __DATE__);
+       const version_t version = get_version();
+       fprintf(stderr, "\nMHash384 v%u.%u.%u, simple fast portable header-only hashing library [%s]\n", version.major, version.minor, version.patch, __DATE__);
        fprintf(stderr, "Copyright(c) 2016 LoRd_MuldeR <mulder2@gmx.de>, released under the MIT License.\n\n");
 }
 
@@ -116,7 +147,8 @@ static int parse_arguments(param_t *param, int argc, CHAR *argv[])
                        }
                        else if (!STRICMP(argv[i], T("-v")) || !STRICMP(argv[i], T("--version")))
                        {
-                               printf("mhash-384 version %u.%u.%u (built %s)\n", MHASH_384_VERSION_MAJOR, MHASH_384_VERSION_MINOR, MHASH_384_VERSION_PATCH, __DATE__);
+                               const version_t version = get_version();
+                               printf("mhash-384 version %u.%u.%u (built %s)\n", version.major, version.minor, version.patch, __DATE__);
                                return 0;
                        }
                        else if ((argv[i][0] == T('-')) && (argv[i][1] != T('\0')))
@@ -175,8 +207,8 @@ static void print_digest(const uint8_t *const digest, const int uppercase)
        static const char *const HEX_UPR = "0123456789ABCDEF";
        static const char *const HEX_LWR = "0123456789abcdef";
        const char *const hex = uppercase ? HEX_UPR : HEX_LWR;
-       size_t count;
-       for (count = 0; count < MHASH_384_LEN; ++count)
+       uint16_t count;
+       for (count = 0; count < HASH_LENGTH; ++count)
        {
                PUT_HEX_CHAR(hex, digest[count], 4);
                PUT_HEX_CHAR(hex, digest[count], 0);