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;
/*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
//=========================================================================================
};
}
- 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
//=========================================================================================
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");
+ }
}
}
}
/* ======================================================================== */
/*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*/
};
/*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*/
{ 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 */
/* ======================================================================== */
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);
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;
}
{
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