Caused by: java.lang.StringIndexOutOfBoundsException: length=7; index=7 Android java - java

Hi i use function to hex string to byte array and it gives me this error sometimes it works some times it gives error
Caused by: java.lang.StringIndexOutOfBoundsException: length=7;index=7 > at java.lang.String.indexAndLength(String.java:500)
at java.lang.String.charAt(String.java:494)
public static byte[] hexStringToByteArray(String s) {
int len = s.length();
byte[] data = new byte[len/2];
for(int i = 0; i < len; i+=2){
data[i/2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character.digit(s.charAt(i+1), 16));
}
return data;
}
error comes in this code and
why it works most of the time and only sometimes it makes application force close,can anybody fix this so that it can work always
i use this function above to make crc32 checsum to bytearray
here is the function i use to get crc32 checsum
private String chesum() {
String fileName = "file.bin";
try {
CheckedInputStream cis = null;
try {
// Compute CRC32 checksum
cis = new CheckedInputStream(
new FileInputStream(fileName), new CRC32());
} catch (FileNotFoundException e) {
System.err.println("File not found.");
}
byte[] buf = new byte[128];
while(cis.read(buf) >= 0) {
}
long checksum = cis.getChecksum().getValue();
String ss = Long.toHexString(checksum);
cis.close();
return ss;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
after this method i call hexstringtobytearray function

for(int i = 0; i < len-1 ; i+=2){
data[i/2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character.digit(s.charAt(i+1), 16));
}
Change the condition len to len -1

Related

How to create jpeg file with raw data

I have the raw data and want to convert and generate a jpeg file, I do that as below, but it does not work. The generated file could not be opened well.
String photo="0xFFD8FFE000104A46494600010200000100010000FFDB004300080606070605080707070909080A0C140D0C0B0B0C1912130F141D1A1F1E1D1A1C1C20242E2720222C231C1C2837292C30313434341F27393D38323C2E333432FFDB0043010909090C0B0C180D0D1832211C213232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232FFC00011080193012C03012200021101031101FFC4001F0000010501010101010100000000000000000102030405060708090A0BFFC400B5100002010303020403050504040000017D01020300041105122131410613516107227114328191A1082342B1C11552D1F02433627282090A161718191A25262728292A3435363738393A434445464748494A535455565758595A636465666768696A737475767778797A838485868788898A92939495969798999AA2A3A4A5A6A7A8A9AAB2B3B4B5B6B7B8B9BAC2C3C4C5C6C7C8C9CAD2D3D4D5D6D7D8D9DAE1E2E3E4E5E6E7E8E9EAF1F2F3F4F5F6F7F8F9FAFFC4001F0100030101010101010101010000000000000102030405060708090A0BFFC400B51100020102040403040705040400010277000102031104052131061241510761711322328108144291A1B1C109233352F0156272D10A162434E125F11718191A262728292A35363738393A434445464748494A535455565758595A636465666768696A737475767778797A82838485868788898A92939495969798999AA2A3A4A5A6A7A8A9AAB2B3B4B5B6B7B8B9BAC2C3C4C5C6C7C8C9CAD2D3D4D5D6D7D8D9DAE2E3E4E5E6E7E8E9EAF2F3F4F5F6F7F8F9FAFFDA000C03010002110311003F00F6FA28A29805145140051451400514514005145140051451400514514005145473DC436B0B4D712A451A8C96638028024A47758D0BC8EA883AB31C01F8D79378ABE307D9E56B6D022460320DCCC3393FECAFF535E57A978AF57D5E42F7D772DD303951249903E8338FD2B3753B16A0FA9F495D78CBC3766E526D6ECC30EAA926F23FEF9CD541F117C264E3FB613FEFD3FF00857CC6F7F719E622A3D8D345E90D8669233DF934B9A43E589F555AF8C7C397A7106B5664FA349B0FEB8AD98E449A3124522C887A3230607F115F22C573295CEF561EBEB5A7A6F88F54D2E5CE9D7F7169275D88F853F874A7CEFA8B94FAA68AF1FF000FFC68DA63B6D7AD09230AD7110C1FA95E87F0C57A9697ACE9DAD5B0B8D36F22B98CF5D8791F51D455A9264B4D17A8A28A620A28A2800A28A2800A28A2800A28A2800A28A2800A51494A280128A28A0028A28A0028A28A0028A28A0028A28A0028A28A0028EBD29934D1C11192460AA06492715E3FE3AF8A4AE1F4ED1A42F191896742507FBAA7A9FAFE5EB5329243516CED7C57F11346F0B1681CB5DDF01FF1EF09FBBFEF1E83F9D78678ABC71AFF008B1C8B9B81059E72B6D136D41F527935CEDC5F2CF2B3B939639214D57DE8C4E56539F7CD67ABDCD2C96C35AD9DF3F316FA1CD41F67393C1E3F4AB5B369046187A30C1A9198ECDC7E71EFD47E35484545DF1E76B30FC6944C0B6D90004F46E9565E35920C44E41EC1BA5565469818A5003FF09EC698890AC903EE53807AEDEF56149980C601C703B56747349012AD929D08EE2A682630B7964831B0CA363BD2B05CBBE647226D67C30E391C83EF5A7E1DF115DF87B5459E165CA7547C94907A6474FA8AC391B77FA420C38E185123078C3E4846EA07F09FF0A2C173E87F0BFC4AB4D4094BC91A3079DB272F1FAFCC3EF2FEBF5AF428E48E6892589D5E371B95D4E430F506BE3DD3B529EC2E53E620A9C8E6BD8FC11E3796CE6315D05FB131CCCA0FFAB6271BD4761FDE51F5A14ADA306AFAA3D868A4565750CAC195864107208F5A5AD080A28A2800A28A2800A28A2800A28A2800A51494A280128A28A0028A28A0028A28A0028A28A0028A28A00291DD63467760AAA32C4F40296B3F5ABE834ED2AE6EEE1808A08DA56CFA0FEB9C63DE93D00F36F8A3E2C9C694D6B6B32DBDBB9D8CA41F36538071FEC8C1E47D33D715E1DF3DCC9F331E7A0EF5A3E21D72EF5CD41A7B876650488E33D14139C5635CCBB104607CC7A9EE6B35AEACD5E9A124925BC2DB51958FAF5A8C5DB2B0DA11BF0A9F4DD1E6BE94048CB13DB15DB5878363441E747BD8F50074A529A45C294A5B1C4F99E728DAA5241E9D2A41E6B0E62FA95EFF00857AADA783ED4A85F2571EB5A71F836CC631101DF359BAC8D96199E31F6372C1A3E327953DEAC7F665CB60B4041038E3835ED0BE09B160410016EE074ABF07846CE188A8E47A11C52F6A2742C784FF00663B22C8C8403C64D46DA534711254943E9FC26BDCE7F075ABC451506D3C81DC1ACFFF00841C213D0AE7D3EF7D69FB50740F14F2D90F03A8C303DE976AA301B7746460D7A9DEF80BF78C5172A0646055393C05232B148C9A7ED513EC19E632C7B485CE71F75BDAB5748D425B69E378D80208EBC8AEA2E7C0572225C0C38EBED5CAEA1A3DEE8D39F3A3207F7BB535352D0995294753E82F869E215D574A92C89C1B7C794A7A85EEA3D81E9EC457755E03F08F561078AA189FFD5CE8F193E84F4FA7231F8D7BF56D17A18496A14514551214514500145145001451450014A29294500251451400514514005145140051451400514514005791FC69D61EDF4FB1D2918ABDD31B89D73CED5E114FB6727F0AF5D1C902BE59F1EEB4DADF8B751BC32168C4A62847A2A9C0FE59FC6A27D8B86F739B4600B3919C0FCAA7D374C6D46E038C919E49F5AA5187B8963B7897259B923D6BD4342D223B3B651B7240F4EA6B3A92E546D469FB4916343D1D2CE2CEDF9ABA6B5B4E4123AF5A4B1B5C95523DEB6238D7B0AE3726CF4D2515616080051C55C8E2C7E3DE9225031C55B54E3B50919C98C58F8A781ED8A78434A0107919AAB117136E78A367183520500F029D8E2AAC4DCAE500ED51B46A3B55964F5A858617247150D14881A08DC608159BAA786AD354B49219630430FCAB558F3D69CB271EB4E3614AEB63C0EEB4EBAF0978A9AD64E064346FCF2339047BD7BEF863C5B6DAEC49138115DEDE9FC3263FBBFE15C3FC4BD086ADA30BB857FD2ED7E6423A91DC579FF833C4F2699A8C4D2B1F2FEEC981CE3D47B8AE984CE3A94CFA728AA5A56A10EA7A7C7710CA2418C33018C9F5FC7AD5DAE839C28A28A0028A28A0028A28A0029452528A004A28A2800A28A2800A28A2800A28A2800A28A280313C61A99D1FC1FAADF23EC923818467B876E063F135F26DD49BA7C0249007FDF55F44FC67B868BC190C2A7026BB5DDEE02935F3BDAC66599E663C29FD6A1EE5AD8DBF0AD8F99A9A36DF963EE7B9F5AF56B2B718500702B88F07DA79AE5C70057A3DAC41556B8EB4AF23D1C2C6D0B97AD6301781C9AB2894C846D5A99783ED592376C9A3241ABD1E0AD514EA0F7AB48FB718AD22CCA68B1B41E29DB062A157E6A40FF4FCAB4BA33B3142F7EB476E94BBBDA9BBB27A629084238A89C0A909E2A17383ED52CB488641935096C1E3A54D230A84F3599A5886ED44D0329E4115E07E26D38E87E25991011139DE9F8F5AF7E90706BCB7E275906582E80F990ED27DAB4A72B4ADDCCAAC6F0F437FE16F8A12DAF63D2EEA4CADD9C44DEADD81FF003DEBD92BE51D2EE5EDC413A64496F2ACA8476E735F52E9F7D16A7A75B5F43FEAEE23120F6CF6AEB83E879F35D4B34514568405145140051451400528A4A5140094514500145145001451450014514500145145007887C69D54CBAE5BE9CAC765B5B6E23B6F7E7F9015E4B68A44078EA6BADF89F76F77F103572321525108FA2A815CFDBAE21403B93591A58EF7C1B1008A3DB9AEF235007D2B86F0683B73F85776831CD71D4F88F4E969045B8F18AB089919A8208D9B1C6055C5D8BC67A7BD42453648910C7153245C6714D4C6719156546056AA262E4C84A1EC28C107A55B007B505148C815A720B9CACA48EB4D63F9D58D80F03141840C52E563E6457C12290C79AB2540A8CE31CD4B882914DD315011CE4D5D7E7355996B26B53452216C115C478F625934975C65BB576CFC5713E386FF00896B8EFDA85BA097C2CF32D381DA14746054E7D8D7BD7C2AD48DE7851AD1DF2F6729403D14F23F5CD782AFFA35B893241F3011F88AF50F8437E135EBBB407E4B9B7DE33EAA47F426BB63B9E6CB63D8E8A28AD8C828A28A0028A28A0029452528A004A28A2800A28A2800A28A2800A28A2800A28A2803E62F8951087C7FAE6063F7C08FAB006B06DC816A093CF35D1FC5424F8F356C83933A819F408B5CC4583005EF9AC99A23D1BC19FF001EC0E39CF35DDC2BBD87A570DE0A42F66A7DFAD7758658895E1BD6B8E5F133D283F710EBBD452D94C7102F2770BDBEB58CD3DEBCA658A399971D00C66B4EDECBE6DC0EECF527BD6B430C11A65880A393934E2BB8DCADB1C98D6EEA39B63298703952A49A58BC4F7F04A04DB8C67A315E3F1AE96E758D0D0849AFED432F6F30122AACD79A3CC02895006E465700D53B74145DF7458B2D7FCF452CB82C3B56B4773E62E41AE5E58238FE687057B62B4B4EBA050293ED494D8E54D5AE8DC0D81B8F7E94D79F6A73D052647979CF359B7B3EC8B1DEAA53B19A8DD9625D4A1894963D3AD64DC78BAC230427CCDD3D6AABD8BDE29123E14FAD25B785B4EDFB9A4CB7A16E951CCD9A38463B8DFF0084B239064201ED4B078844F36CDBD3AE78ABA9E0DD295CC811998F5CB714B3F87AD1147930AA6DE4629B892A6B62D330740CBD08AE2BC6CB9D35F9C135D3596FB794DBC99D8DCA9F43E95CDF8F976E8F2B7A63F9D42DD0DE89A3C9F5090ADB40A7AB499FC2BD0BE12AEEF17DB64E365B3903F0AF3CBEC32D99EB8E48AF47F83C86EBC6534C14797059B11EC4903FC6BB5743CE7D4F73A28A2B5320A28A2800A28A2800A51494A280128A28A0028A28A0028A28A0028A28A0028A28A00F9F7E3469A6DFC671DC7245EC2AE3D8AFCA7F97EB5C1C49F291D81FCEBD3FE2EDD26A7736D2C6EAE2D77A851D403DFF00315E796F092625E4EF7FE558F3A7B1BBA72834A47A8F82EC8C3A4C6C47279AEA88079C671DAA8E8F08B6D2E18F1D1055A30866CE07E55C5296A7A118E962A6A9AC0D3ACFF75099676E12251924D7137FA7F88F5EB5B89B51927B7E3315B47C291EF5E8B0D8C68776C279CF1D5AAD84509F7703FBACBC5383B6E124AD647885AE93796EA206D31CAEEC991A3249EBC7A735E856BA5DAD9F87AD4249E5DD85CCA814B29F63EE2BAC658CF1B500CE78CD4125BC1C928315B395D58CE314A5CC73902ABC2DE5BB473852C114E41FF0AB7612BACF116EAC39FAD5C91460A43C023E638E83DAAB4087ED4840E178158CB7B1D4B53A549098C0E2B1EFE461305E3D066B522271D6B3AFD7372983834A5B1115A983A85C933790B2B48E78C29DAA3EA6B9BF1035FE93A840A2F41B574DCFF67C027D831C9AEFBECD14ED9740ADDF1C66AC8B0B7600490A381D03006B485B726ABE6D0F2FB2D675E96F9174BD4E658E473B52E083F28EEDD715D3E99E3C963BDFECFD66DCC72E7689907C8DEF5D545A4D82E76DAC60E739E29B7BA4D9DCC4639218F6FA003344E48CE2927A9332A4C56442083CF06B9AF1EDB97F0EDCB019C2D741696CD664448DF201819EC2AA78920FB57876F62C6498CE2B38BD47256D8F9FAF59B108EC11715EAFF0411BFB5753720FFC7B800E3FDB15E65730868ADF079008FCABDE3E137874693E184D42420CF7EA1F8FE1404E07F5AEE8EACF3A477D451456A66145145001451450014A2929450025145140051451400514514005145140053263B6090FA29FE54FA8AE7FE3D66FF71BF952635B9E49E23D363BBD36750BF300C49AE074887CED5AC62EC0D7AD3DBECB09A771BBCCC9C7A03D2BCE34487678AC8DA42C6481ED9AE24EC9A3D6C42E69C59E9F08022503A01C55A8B008F535562FB8335617839AC5948BC98039A4765CE0134D8D59BAF6A9C460AF4156913A22990CEDF2834BF675032D93577C9E7DA94A0C1E00ABE5072EC645C2F1B40FCAAB471E2451D31E953DD5CA6F644E48EB51DB2316DCFC13DAB37B9B2BA46AC43E5EBDAA8DF27EF15BB568C3165338ED515D4584208AA71D084D5CA9182782335602100E18D47692AABF9520E3B1AD45851B907F2A515714DD999F8607E6E7E82A64DAD9C60D58680E781513463B7047A537168574C6141CE4556B98F7DACB1766523F4AB2CD8E33F8D44DD718EB59ADC867855AD83DDEAB1DA2004B4A463D81C1FD2BDFBC213A1D30DA22145B7014293D3B7F4AF29F0C5929F175E1E71049264FA64D7ABF8517F7133FF78E7F535D506F9D2339538AC3CA4F7B9D0D14515D479C145145001451450014A29294500251451400514514005145140051451400535D3CC8DD0FF1291F9D3A8A00F3EBAB8F95AD597231B6B8F4B3FB3789E2754DB1CA060F5C15EBFCEBD0F52B0824D5E50D1F0ADB87E3CD624FA7F977EB21036A9CA0FEB5E7BBA7667B32946704D7A97630401C5581512F0054919C9ACDEE28B2F44700135723C7B5504600558127191D6B5831495C9A595546011CD50BAB9DB048C3A81493CD96DA0F350C830A549EBC1A6E772A3048AD6DE5470F9923282464926A05D52D2698A5ADD452B2FDE54704D23DA15F9762CF1F64638C5645D787ECA6B9FB54109B7BA439568CE39ACCDAC9EB73BC86E63FB2C7800311CD41A8DC471C439193EBDBDEB9D4BD9D618D7692CBF7A96E54DF6D697718D7FE599E327DFDAA9D46D58C552D6E68C135B4F1931CC8E41E769CD68432B0406B120B1557F336C716472B18EBF5AD34CEC233CF6A94EC54E28D38A40E9D71448063B66B3ADA7C3956386156DA5C826B572BA3271B3229463E95093FBC19F5A7C8F9A87AB0158F507B1CDF84F4F293EAD7520C1B8BA62B91FC3935DFE876FE458938C076C8FA7F9CD7190DD3C33982304E093D2BBFB3564B2815B8608335D346CE4D99E2D3A74947B93D14515D479A145145001451450014A292945002514514005145140051451400514514005145140181AD109A821C632832477E6B12FB9B98BDD4E6BABD4B4EFB6857460B2A7033D08F435CF6A3A75EC2F1CAF6FF00BB4C86752081F5AE5A907CCD9E851A90704AFA9507414FCFA77A8C1F996A6C6074AE496E744762CC2011ED53380919CFE150C1D053EE01DA31D68520DD9573B14B100B13C9A89E6C92481D68951B6E4E460679AAAB20DC4B3F51DE9DCD3726CB6E38E4FA7A52471BC8E30BB4F7CD466E23FEF73DEACC534783CB608F5AA516C1A63F728382A188EE6A09449B738C96FCE9B27D97EFE589FF007A9C2E63098FCB34DC243507B91C45C939247D0D5A490AB28CFE354DAE602321B07D29D14A92B80A6A354368BD38257CD4E5D7F5A9A19FCC881031EC6848999001D31447179701DDCF3DA8E633BA6AC46CD938F5A72FDE3DE88937483FD919A338622927EF112D8B36D6F1CB7702EC041619E3F1AE9AB9DD2D8A6A51A9E7208FD2BA2AEFA0BDD38B177E7498514515B1CA145145001451450014A2929450025145140051451400514514005145140051451400541789E658CE9D731B7F2A9E8A011E7F9F9B8EB572325B150DE43F67BF9A2C7DC738CFA76A58240C40CF23A8AF2E71B33D783BC6E5B806D18F7AB650B019AAA061855E8CFC9C524852672FE287D422457B5E235E5801D6AADB68D7F73134BF6E5703691B57AE7AFE55D2DF0EA48C8C60E7D2B9C669F4E95CDB48446DCED3574F9766691E669723B337A3F0920B8883DC48F191CF6E6AEC1E1784DCC8BBA50A318F98F354ECFC4EB3BC21D3CAC0C12790C7EBDABA3B6BB6688CADB7040C6C39AE9518F439AA55C44349192DE19B737423DD273CFDEE31531F0C59A5C20F2CB260E77126B504F9973B0F03AD51D575836908749225653CAC8092C3D0629D910ABD693514CA177E18B4304DB536313F2107A570DA86997367AC35B59DE3C8CC385EA14D74979E24BA9ACCC512E1D9B265C6D38CFA547A3DA6C2D7329DD2B9FBC6B19B8A3B29C6B4173547F2356C2D9EDED63576DD26D0093DCD589942C6062A44E82A2B87CE7DAB07B195EEC860036C8C7D71459422E6F16324856EA475C5337058B1EBCD5ED0E3DD73249FDD5C7E26AA8C79A689AB2E5836695A6990D9B99159DE4E9B9CF415728A2BD2492D11E74A4E4EF2614514532428A28A0028A28A0029452528A004A28A2800A28A2800A28A2800A28A2800A28A2800A28A28039AF135B18DE3BC45E1BE490FA1EC6B120601F23B8AED7548567D2AEA3619FDD923EA3915E7D04C164C13D3D6B8EBC75B9DD869E9666EAFCCBCF5AB314BB545508240CA79071522B9E45729D0D166750EA7D0D65C96E1B28466B495C15C30CF6A6B202D914D15176461AD83C527AA75C7A569C114B1A1F227703FBB9C7E9569610DD7AD35E0639033C77ADE32B22DD6BAB4861B9D4241CCCEBC609500715464B68F2C6526473F89ABC23988032187B76A992D72727A5539F9046A463B7E06341605DC3B8DAA3A2D6AC2BB48006054ED1AA800520E0F15CF27A932A8E7AB2756C2D57958B71EBD6A4270951310AA49EB506688A66C0DB918AE8749B73058A9618793E66FE9FA5626996BF6FBDC9FF53110CFE84F615D4D76E1A165CCCE5C4CFECA0A28A2BA8E40A28A2800A28A2800A28A2800A51494A280128A28A0028A28A0028A28A0028A28A0028A28A0028A28A0064EBBADE55F5461FA579A5C407EFA1C30EF5E9AC32A47A8AF3ED9918C77C573623A1D78657B95AD2F46423707BE6B4BCC19045645CDB9DDB9090DD8D4715F151B64241E9CD7234759D086CE304559519158305F7EF3048DAA339F5AD7B5B859A3C8239F4A2C3B96D1950F5FAD48D2A1E322A011EF0769A745096E0F03EB571B834B726DC9C6318A0C800EB4184636D46D1ED18269BB92921ACC18F06A189A4676F300001C2FB8A460E24181F281C9A8A7B958863F88F02B268B7648B06404E73C0AA57373B80033ED8EB51CB73B1319F98D3614DC771E49A496A458E97C36BB6CE6E724B8273F4AD9AC8F0F9FF469C7A38FE55AF5E952F811E756569B0A28A2B4330A28A2800A28A2800A28A2800A51494A280128A28A0028A28A0028A28A0028A28A0028A28A0028A2A1BCBB86C6CA6BB9D82C50A1763EC280399F1CF8CA2F0B69DB61DAFA84C0F9687A20FEF1FE9591632F9D04726721D0367EA335E4DE28D62E35AD62EAF2E1B2EFD17B2827803E8057A2784EEBED5E1DB17DD9611053F51C5736236475E13768D9962CF38ED599756BB8671C8F4ADCC6E5E955A6871D338AE53AD9CBCE92A11E8390DDC55BD3B57F298473101B3C62AFCF6CAE318CD62DDE9ED13E42165EA41A6990F4D51D859EA28FC123F3AD486E623800F26BCD2192488E239DA33FDC93A568C1AB5EC6B8F2C330EEA69A9587A33BE69541E587355E796319F9BA7415C87F6DEA2E9810AEEF76A824BBBB646134EAA7D23E48FCE872B8F447437FABC709F2E3F99CF1B456524CE5CC8F9F309FBA0F4AA96D1B48F98D0EE3D647EB8AD6B5B355009EB50D8D216084C982C38EC2B436630288A221B3DAA57C2D24522383C476FA15EDBC17785B7BB72A65FF009E6C3A13EDEB5DA672320E41EF5E25F102E04726991E7EF3393F4C015DAFC35F1136A9A39D3AE1CB5C5A0F9198F2F1F41F974FCABBE8BF711E76257EF19DC514515B180514514005145140051451400528A4A5140094514500145145001451450014514500145148EEB1A1791951072598E00FC68016BC9FC79E2BFED367D3ECE4FF00428DB0CE3FE5AB7F80ED5A3E36F1AA3A3E97A54C19586279D0F07FD953E9EA6BCDA42197A8E7D6901CEDC125AE0E73F3819FA0FF00EBD775F0D2F849677762C7E689F7AFFBADFF00D715C03BE4DD0F4909AD5F06EA8BA6788A2676C473298DF3EFD2B2AAAF166F425CB347B745D3A734AF186078E2A382459143035615782C3F2AE24CF4199CE9863C7D29862126411C8F5AB73A1249039A85305C714EC4B332EB464946E518359ADA2DD21F91C81D706BB48911D7A0AB1F654206467EB4D23367111E8B76EBF3C9B7DEB42D7C3F1A00CE4BB1EE6BA836C00C019A6B461171D0D26868CE8ED123F976E3F0A9634F98E0F3529EB5246BE9516344204DA09A89CE6AC13CD65EAF7F0E9D632DCCCDB52352C4D32E279AFC42BE137896D6D94E45BC596FAB1CFF002029BE17D667D175E1750B0CC6F8656E8CAC3915CA4F7B2EA5AB4F7B2FDF9A4DD8F41D87E55A36AE3FB4255EA4A822BBE9C6D148F2EB4B9A6DA3E94D2757B4D6ACFED16AFD3878CFDE43E87FC6AFD784691AF5DE8B791DDDABE0E00743F75C7A1AF58D1FC63A4EAC91AF9EB6F70C398A538E7D01E86B43237E8A28A60145145001451450014A2929450025145140051451400514557BEBFB4D36DCDC5EDC470443F89CE33F4F5A00B155AF750B4D36033DEDC47047EAE7AFD07535E7FAEFC50DBBA1D1A0F6F3E71FC97FC6BCEB51D56FB529DA7BCB996690F763FE71480F4AD6FE28C30068F4AB6DE738F3A6E9F50BFE35C2EA1E24D4B5B72F7B7724880F11E70B9F6038AC02C40F5278AB200450BE9D7EB400F3212DC9FAD34E09F5A3273FE1428DE4E28039890E2FAE93D4D537CAB706AD6A07CBD5A418E180355A5033C5203D17C11E3500A69DA8BE18E16299BBFB1F7AF4E8A50CBC57CD0A4839AF4AF04F8DFE68F4DD4E5E7858A66EFF00EC9FF1AE6AB4BAA3B68D6BFBB23D464019491F7AA9104B607153F99C0C74A4C073D7E9581D16085BCB6C1EF5A50CA081CD515418C1E0FA1A9150A9E0D589D997DDC01559C9639A728247CC734BD3A0C527A896840D1E0824FE14A3273C53DBDCD4324A154F350CB4C259022939E71F957947C46D6CCCF1E9B1BFCA4EF900F4EC2BB0F12F88A0D26C9E495B2C461133CB1AF17BCBB9350BD96E66399246C9F6F6AD68D3BBB9957A9C91E5EAC2DC61C35685930FED5EBD63AA5180800A9B4F707598C632769AEC479E744AC36E29E92100AB72A6A1604673CF34A0F1914C4741A478BF59D1088E1BB3242BFF002C66F9971FD3F0AEFB48F891A6DE6D8F5089ACE4EEE3E7427F98AF2224B019E48A5538638FAD007D1B6F7305DC2B35B4C9344DD1E36C8A92BE7FD3B59BDD3271359DC490B772A783F51DEBBED17E24872B16AD08F4F3A11FCD7FC2981E854556B2D42CF5287CDB3B88E65EFB4F23EA3A8AB3400528A4A5140094557BCBEB4D3E0335E5C470460672ED8CFD077FC2B88D5BE27DA405A3D2ED8CEDDA59BE55FC0753FA5007A063358DAAF8A747D1C1173788D28FF96317CEFF0090E9F8D790EA9E31D6F562CB35F3A45DE387E45FD3AFE35866407D7DCD203BFD5FE27DE4BB934DB74B64E81DFE773FD07EB5C35F6A577A8CED71773CB34A7BC8C4FF00FAAAAE79CF34BB7D7AF5C668018DC1CF3ED4C2C718E2A6231C541236073D3DA9804403CB93C85AB180467144516D8957B9EB52140383EBDA9011E4820D390F5EF4D3F4A72F0076E7AD3039AD7E331DFC72606186335473915B7E248F75BA3839DA7358719040A402ED04533186E73528EB4D71C5033BDF08F8E9AD82586AB21687858A76EABECDEDEF5E9D0CCB22875604119041CE457CE238AEAFC2DE32B8D15D6DEE0B4D624F4EAD1FBAFF0085615297589D54ABF491EE11B2BAFCD532A7A1CD62586A905E5BA5C5BCAB2C520CAB29AD14BA0C301856074DBB1780E3A5359F02AAB5D85E335565BC2C719C0A4C39596259B1F2E79AE7BC45E22B6D16C9A5998173C2203CB1AA1E22F16DAE871329224BA23E5881E7F1F415E4DA96A575AADDB5CDDC85DCF41D947A0ABA74DCBD08A95953D16E3F54D56E758BE6BABA7C93F757B20F4155E250324D44064D585C05E2BA924B4381B7277623310BD79A4D224275C8FF00DD34D90D3B4319D710F600D52133AB93B64F3D3EB4C1D31C5492A9CFA1FAD464118EA4D021EB81D4FD3141CF3D7E948A71C8A7F5E707F9D30101E3A54884AF538C5443E623B0EE2941C938CD0068D95FDC59CAB35B4EF14ABD1D1B06BBBD1FE23CABB62D521128FF009EB1E037E23A1FD2BCD94E39C1C83EB4A84EEE01F5CD007BFE9FADE9DAA28369751BB1FF009664E1C7E06B42BE7A8AEA488AF278E841E47D2BA8B1F1A6B105B08C5F160A78F31031C7D4F3401C96A3A85DDFDD34B757124B21272CEC4E2A9E3279A795F9DB8E734D0B8F4CD201BB4038F5A5038F5A7E0000E38F7EB4D0A3A5001B79C76EF9A7E79271903DE8EF8DB8FEB48DC28C1F7A6031987F09FAD44AA659BB155E695DB0BEF4FB6DA611B48627EF7B1A009C201D40A6139CE69E5C0E00E2A2273C2F3400BB739EB4A7E5200E4D359B6FCA0FCDFC8D3118904E39CF5A008354877E9F271CE0D72509E0576D7196818631C57158DB23AFA3114809FB6690F22914F6341A061B734DC62A40334A40C50069E85E23BDD06E7740DBE163FBC858FCADF4F43EF5EBDA26B567AE588B9B490F1C3C7FC487D0D78601CE6AD58EA779A45D19ECA53148CBB4FA11EF594E9A96A8DA95671D1EC7B95DDFDB58C465BAB88E251FC523015C1F887C7E8375BE93F331E0CEC381F415C8DA69FACF8AF50710CCB7572ABBFCB7994311FEC8279FC2A8CB6EF04EF14A312236D61E84528D14B5654F10DE911B2CB2DCCAD34CED248C72598E49A455C9A52B838A78E0715AD8E76C5D985E3AD0A7029493D0D340E4E78A00639C8AB1A0A13AA338C12077AAED57BC3F9FB5CDF85342674B229607A54382B8CF03D2AC331278E83F5A8D86E3D00EF4C045C0C8E9ED4A3078C9C7D690F3DB38A453EF8FC2801AC304B7AD3C13C1E31EF43ED452EE7FFAF446498F0463B8E6801C011DFA76A7024F503EB9A400B2F2C73DE973C8C76F5A600783CD5AB771E59C9E73E95588E84F39F6A9635F94E01C669010151BC9C9EA69303271CE3BD3E4FF005878C60D373B718EB9EB400846072700D03AF3CFB52B0C9A5238DDC73C50034E7B6334D7C91D31CFA53BD7814C276FCB9FA8A0444E85B8C702A9CA92452F99136D6EFE87EB578B82085E49ED4C16ECE4971B47EB40C8E0BE49DB6C8BE5C9E98E0FD2ACFDE3F2F029C96D146095500F73D4D03D01C50044460F149820E31C1A7B0DC4E3814CCF1C75068026C62220F5C57177236DF4C3FDA26BB55CB752335C86A6BB354947AE08A1810A9E29D4D51C53C5200CE0D3B19EB49DEA7B5B59AF2EA2B5B7469269582A2A8C924D004124B15BED79559D370CAA9C16F500D76E60F08F8CECE38F4EB74D37548D00007064FF007933F31F7539F6ABF73F0F6CA1D323B7D76DA6B19C1222D5AD2433C2D9ED2276FC307DAB87D7FC19AB786CC77132A4F6321FDCDFDAB6E89FD391F74FB1C1A1810EB1E1DD5FC38EB3CF62A210DF25DC0C5933F51F74FB1C1AB177E29BBD7EDE34D4EDA396EE20156F106D91C7A3FF0078FBF5AEA7C21E319622B61AF3FDA2D241B3ED122EF641E920FF00968BF5E4763573C59E04B7D3617D6348402D061A7815B70881E8E87BC67F4A4981E7FC30F7A403079A8DEE10DD6DE81BA7D6A43CB7BFA5318A4934DC734E1C76A0F5E280227E957BC387FD22E0919C11546438539ABFE1AFF59367B9142133A4241FE1C7A5386DE724629A78207A0CD1C6C231DFB5301E7681918FA546ECA8A18E001D4D3B04F7E00CD38283C7502988CF25AE640EC708BF747F5AB6140DA41A468003B97AFA53C71C1EB40C78072401C9F5A41EFD0D286E8476EE69AD8248273E94002918273CD5A831B09C1E4F6AAC09CE7F954D1394523DFD280227F99C8F7CE6A323E61EE6A4707CC3EB9ED4D66032768E29084E7248E94A464918E075A14719FC69369C1386FF001A603791D8FD7AD4172E5636DA7E603AD4CD9E80F1EF50CA01041E9DE8027B765F2D766002323DEA5EE723B67154AC0E6231FF00CF3623FC2AF01D0AE2801802AE79C64669833D0726A5DBB739C533A9A008882783834D00027207E34E627A74151A8049EB8F6A432CA9C6707A7A5727AEAECD490FF796BA98BDFA0F5AE73C509B25865039068623354F14F14C4C15C8E98CD380E47AD218F5F7AB7A5EADA769BAAC7F6F4BB2A4644B6920592139E187AFD38AA6D88D0B9E83F53E95962D24B9B96D873331C853FC5EC3DE803E8AD1BC5727D83ED32CE9ACE92DF2BDEC0BFBC8FDA68CF5FC7F3AD88F45B596DDEF3427866B2BA189EC5BE6B79C77001FBADEC79F4AF9B346D6752F0FEA02EB4FB892DEE17861D98775653C11EC6BDAFC09E28B2D76E0C9A704B0D5587FA56984FEE6E40EAF17A1EF8EA3B509EA339FF17F82D7458CEA9A6A3FF67B361E26E5AD98F63EABE869FE03F16E66FEC1BCC488EAC2D83F46047CD09FF658671E86BD635158EF2CE46110994A149A16FF00968BDD4FB8F5AF9BFC5FA5CBE15F1029B5998DBB91716530EBB73C7E208C1FA5262454F18E93FD83E269ECE125AD89135BB1EF1B723F2E9F8555B39FCD8C17FBE3EF7BD69F8C7598F5FD52DAE23006D814311D99BE623F024D62A298B6BAF51DBD685B0CD23EB8A43C669A8E2440C0F07A539A98114C32BC77AD1F0E1C4D3301E959B3B6067D0715A7E1A18926CF6C53423A323058F7C518C8C91CD2838EF9CF34E61C6473EB40840ADB724D19EA470691D84519627E526A38EE637182E37771D29812FF00C0BDA9B83CE453B8EDF8D200318A0069C28EF4BF771807DE9922E5003EB5230F90F3C50319B8EFE01E956603FBBEBDEAB36401F313562023CBFBB9E680226FBCDC73BBA537664E4FD49A7BF32301EB4857FBBD7340814718C72280C40E690E71D7927AD213C633400D3B8609A8A4C7271D7F954A4823FF00AD4C2BFBBCE68029DB1F2EF4AF389173D7B8AD34E87273E959736E8E58A4C7DD6F4ED5A48C3B66801EC3907B9EB4C619241CE4F6A5E7A9E39A46E79CD0042CBCEDC8A4C90411DBB629597E6240F6CD20E09CF1DF34864919E08C561F899736E9EA1AB701F907F4ACBF10A03A7B1C64820D0C47356A7E4C1EDC558C1C8C753D2A9C1F7F6FF7B8AB723145F2C6379E0FB0A432299B7B051F717F53EB558AFEF1707073C1F4AB2DF2AD57670A771ED401D55868C3C656412C87FC4E605DD264610A0E3E76EC7D0F7E95662F00F89746BC59844AB3429E7978A603C90A32599891B715E9DF0E3458347F0B5BCB082D737C05C3BB8DBDB8273D140E99FAD721E3FF00170D5125D1F4B90FF6786FDFCE3ADD30FF00D90761DFAD16B01BDE0FF88B17885DE19891A9C3117940181728BD580ECE3AFBD711F142E6DEE6EE0B78195E32FF006984AF40AE3E603DB2335CFF00867C3F75AD7886382D9DA1863FDE5CDC02408A21F78923D4718EE4E2B47C796B0597898410487CBF215920239B75249543EF8C1FC6A7A8CE6228BA7153B28C6295050E302A84471B7932609F909FC8FAD5F1C8CD51601D0D49693160626E5D4617DC50319390C5547739FC2B6BC383E6B8F6C561B7339EF8E056EF8748F3E6EDC8A6846F76E3D297B6724629C7AF07826800007DB8E9408301D406C1F6AAD25946C72B953E839156D07209A42C7711C7E069814A34B8B77009CC6474CE7FFD5568005471D7BD48DCB6D3E9C7151B282DDB8F7A006CA732A28E78A776C1CE4531FF00D7E31C8C54A41241A0631BE5233DEA6B70BE59C8EFDEA171EC01A920E10F04F3400A48DE727B9E94600E074A523058E463A5260123BD0211B1C01CD31BAF00600A71197E69B8DC4F031D28019C8E08C5249D38E7F0A7E7AD46C7E6A00AD7281D1947A75A9ADDC3DBA311CE39A57518F5A82DBE5DF1E790723E86802E9248CF149D88A542186D34857D0FE740119DA3193C8F4A69EBDB03D2A42AB9FAF7A43C76EA3E94862A803E53DCD53D690BE972F6C0AB8A7902A2BF8F759CAA73F74D023854FBD56630076AACA306AC4679A43125E168D32C5F55D6ACEC1012679557819EA69B3B002BB4D363B7F08E8B0EA1E403ADDD022191CFCD0E47551DB0A7AF5C91401D678F3C522D206F0F6992004288EF2643D80C794BEC3BFE55C3691A3DDEBDA8C5A7D8C7BA693A93C2A2F7663D80A8E1B5B8D42F22B6B789E6B899C2A22F2598D7B069D61A57C3FF000BCF7178EB230C7DAA543CDCCBD44319FEE8EE7F1A00CAD565D23E1C7851520559A490E61571F35ECC3FE5A3FF00D335EC3FFAF5E2134F737F753DFDCBBCB2CB2169256EEC79AD2F156BF7BE24D665D46F9C176F95117EEC483A228F415D55A78705AF80B51374A5654B64BA718E56466CA29FF80E0FE353D467131F4A7B2FCA69919E01A95CE56A845743DA865039EF401F352C9400D8979F6ADFF0EE049393D320561C43835BDE1D1CCE7FDAA680DD23278071480F5F989A7E7E5383CD346319FE54085191CFEA29C76F427F1C528E3A372074C500E7B649E6980CC64920D20C93806970A48CF514050791F8500349CCAE47AF6A9368DA33DBAD44BC8CE39CFE15229E79C508631B19C63247AD4B0E761E40E6A27C1239E4FAD490950878CF3D85021E48F9BA75A418DDD3927348E36330A07098E33FCA8108D819E73ED51139240E062A46C6083CE2A238CFB1340C71238A6E3739078ED4A70070793403C640CD0046E00380411F4AAA0EDBBF665C67DEAE119C6073DCD54B8182AE3A86CD005A46E29DC670BDF9A895883CF3F5A99946CDD9E4D003581C8E7EB4D6E00C76E94EE0AE29A4E78E82800CED26A4917CC84E0678EF50F7F71D7356010613CE7B62803CF241B6575F4635345CF4A4BE5297B3A91D1CD1074A919A9A0E9E351D7ADE2750D1A1F31C762179C1F6CE3F5A8F58D58EADAF3488E5A08FF7711FEF0CF2DF89C9FCA8B5D44596997B1404FDAAEB1133FF00722EA40F763C7D07BD75DF0CBC286E6F63D6AE60591124D9650B8F96494725DBFD841C9F7C500773E0BF0E47E1DD31F53D49960BD6877CD230FF008F3848E9FF005D1BD3A8CE2BCFFC6BE2697C45A80601A1B1B7CA5AC19E157FBC7D58F735B9E33F152EAD31D2B4F99A4D3E172D2CDDEEA5EEE7FD91D87E35CE68FE1EB9F126B096301F2D00DF3CCC3E58631D58FF004F534010F843C3D1DF5CCBACEA3116D2EC181F2CFF00CBCCDFC310F5F56F6FAD7A6EA3666DB47B6B5D4486B9D46F04F780F655F9DC7D00551F9D6CE95A3DA2A5BB451AC1A4E9C08B4493A330FBD33FA9EE7DF02B86F1DEBE1747BCD4C92AD7AAD61A6C6C7E61167F7B29FAF4CFAB1F4A9921A3CACDC2DC4D24C8A111DD9828E8A09C81521E56B3ED8E015F4ABE394AA02303E6A24E4D0A79A6B1CB714089A3C05ADDF0E6364FC7F17F4AC3C6D415BBE1B03C894F425C8CE69A036CE0F6FA8A41F7BDA9CD95071D33C1A0025FD47AD0217DF278A3E600B0C71C53874E7A534819E99CF4A6023678CFA7A51850BDB03D0D047CE383F4CD237DC73EDD31400C5C989724FD314E52320FAD391405C1FAD38631C0C9A008D946086C023A54909DA8402719F5A6363A93D78E29D1AE54F03AD003DF3E6373819A69CB71C648E6948667386EFDA9A46E272706810D6CF7C1A839278FC2A7700707A8AAA3396CFAD0344E010B818E98E690718073CF7A45CB70453F8CF4C6D1400C0700E1AA3957CC47E3B75A9362E3D0FA5211CE07208E68020B7625149EBD2AC8E4118E2ABC6A04AEA7D7233DAACAF5DB9E9400D38048E9CFA534F390339A7F439033EF48E39CD0033EF718A9A305931C0CD440F3935221C92391480E27594F2F559C0E84E6A0B7FB9577C40BB7546F75154A004C3C024F603BD219AFE18D0A4D7F54FB386F2E05CC97136388A31D4FD7B0F52457A1F8C35C8F42D31742D3904171342239114F36B6DD562FF7DBAB7D7DE974D8AD7C07E0D5B899524BC720953FF2DEE7190BFEE479C9F56AF3B334F7D772DCDCC8D2CF3397776E4B313480D1D22C6E350BC86CED2232CF336C4403A9AF6FD0BC356FA4E9BFD9B036EC90F7D72A3995FB2AFB0E807E359BE07F0A1D0AC84B3A0FED6BA8F2FBB8FB34479DBEC48E4FA74AEBE666B78520B407CE7E221DC67AB9F73DBD055A4230FC437313C52D81996D74FB64F32FE71F7628D7A20F5F4F7635F3C78B7C40FE24D71EEFCBF26D63510DA41DA2887DD1F5EE7DC9AED3E2378A23BACE83A5CBBACA19375CCEA7FE3E651FFB2AF6F5EB5CEF81BC2BFF000926BC0DCA37F665A625BB61FC433F2C63DD8F1F4C9A8651B29E15165F08DEFE6091DCCD2A5E3B38F98467E48D07B9C96C7B8AE290FCB8AEF7E2EF88775D41E1D81940B7713DE04FBBE6E30B18F645E3EA6BCFE13914201A38269ABCBFE34BD18D2C3CB5311331C0ADEF0E28FB2B9238DE6B9F73D6BA2F0E7FC79F4FE2269A066CE4AAE07AD19DAD8007F8D07248C77ED40C9C93802810E0CD827B76E28182016EA29491B7078E7AE681C7BD30180E5BF1FC6924394E4F538E6970093914C906022E3BF7A009768C06639FA5203B72DB4E29FD62E3191E948589EA7B7A50046572CC1781EF52C0008F9F5F5A898ED20E39FAD4F06761FAD3026F29031C2F7A1E240385EB451480AF2C69B41C738F5A8C449FDDEF451400F4893238EDEB4796BB18E3B8EF451400EF2D3D283126FE9FAD145022BBC482E970BDAA648931D3F5A28A062BC4983F2F6A431271C7EB451400C1121DD91D3DE9E235DDD28A2901CC789608FF00B414EDE76FA9AA365122AC6CA3043020E7DE8A290CECBC7A4BF8896D589305B5B44B0A678405431FCC9249AB5F0D6C2D6E3C5B69E742B208D1E550DC80CA09071DF07D68A2840CF6BD3544912BBFCCD2CD8727F88019C1FC6B9EF175D4F0783F55BA8A5649DD9223203CED638600F6C8A28AB7D40F03B8823C9F97F5AF6CF03DAC1A7F81B4E92D6258DDEDEE2ED88E774CB9018E7AE0018ED451598CF9FAE07DA6692798B492C8C5DDD9892C4F249AB56D0C7B47CBDBD68A2840C6B431E4FCBFAD3E1823DDF77F5A28A6215A18F27E5FD6BA4F0FC118B0FBBFC47BFBD1450819AFE5261BE5EFEB48224C0F97F5A28A62078D42A8C7BF5A72C498FBB4514C00429B54EDE49E6A19517ED0463A5145004BE5260F1FAD46635C118FD68A2980890C67AAF7F5AB1046BB5B8FE2A28A00FFD9";
InputStream is = new ByteArrayInputStream( photo.getBytes());
FileOutputStream out = new FileOutputStream("C:\\test.jpg");
byte[] data = new byte[1024];
int readBytes = 0;
while ((readBytes = is.read(data)) > 0) {
out.write(data,0,readBytes);
}
out.flush();
out.close();
is.close();
What if I get the string like that, it looks like not the hex
String photo = "/9j/4AAQSkZJRgABAgEASABIAAD/7gAOQWRvYmUAZAAAAAAB/+EUhkV4aWYAAE1NACoAAAAIAAsBDwACAAAABgAAAJIBEAACAAAAFAAAAJgBEgADAAAAAQ....."
Just remove the 0x with substring and convert hex string to byte array :
try {
String photo =
"0xFFD8FFE000104A46494600010200000100010000FFDB004300080606070605080707070909080A0C140D0C0B0B0C1912130F141D1A1F1E1D1A1C1C20242E2720222C231C1C2837292C30313434341F27393D38323C2E333432FFDB0043010909090C0B0C180D0D1832211C213232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232FFC00011080193012C03012200021101031101FFC4001F0000010501010101010100000000000000000102030405060708090A0BFFC400B5100002010303020403050504040000017D01020300041105122131410613516107227114328191A1082342B1C11552D1F02433627282090A161718191A25262728292A3435363738393A434445464748494A535455565758595A636465666768696A737475767778797A838485868788898A92939495969798999AA2A3A4A5A6A7A8A9AAB2B3B4B5B6B7B8B9BAC2C3C4C5C6C7C8C9CAD2D3D4D5D6D7D8D9DAE1E2E3E4E5E6E7E8E9EAF1F2F3F4F5F6F7F8F9FAFFC4001F0100030101010101010101010000000000000102030405060708090A0BFFC400B51100020102040403040705040400010277000102031104052131061241510761711322328108144291A1B1C109233352F0156272D10A162434E125F11718191A262728292A35363738393A434445464748494A535455565758595A636465666768696A737475767778797A82838485868788898A92939495969798999AA2A3A4A5A6A7A8A9AAB2B3B4B5B6B7B8B9BAC2C3C4C5C6C7C8C9CAD2D3D4D5D6D7D8D9DAE2E3E4E5E6E7E8E9EAF2F3F4F5F6F7F8F9FAFFDA000C03010002110311003F00F6FA28A29805145140051451400514514005145140051451400514514005145473DC436B0B4D712A451A8C96638028024A47758D0BC8EA883AB31C01F8D79378ABE307D9E56B6D022460320DCCC3393FECAFF535E57A978AF57D5E42F7D772DD303951249903E8338FD2B3753B16A0FA9F495D78CBC3766E526D6ECC30EAA926F23FEF9CD541F117C264E3FB613FEFD3FF00857CC6F7F719E622A3D8D345E90D8669233DF934B9A43E589F555AF8C7C397A7106B5664FA349B0FEB8AD98E449A3124522C887A3230607F115F22C573295CEF561EBEB5A7A6F88F54D2E5CE9D7F7169275D88F853F874A7CEFA8B94FAA68AF1FF000FFC68DA63B6D7AD09230AD7110C1FA95E87F0C57A9697ACE9DAD5B0B8D36F22B98CF5D8791F51D455A9264B4D17A8A28A620A28A2800A28A2800A28A2800A28A2800A28A2800A51494A280128A28A0028A28A0028A28A0028A28A0028A28A0028A28A0028EBD29934D1C11192460AA06492715E3FE3AF8A4AE1F4ED1A42F191896742507FBAA7A9FAFE5EB5329243516CED7C57F11346F0B1681CB5DDF01FF1EF09FBBFEF1E83F9D78678ABC71AFF008B1C8B9B81059E72B6D136D41F527935CEDC5F2CF2B3B939639214D57DE8C4E56539F7CD67ABDCD2C96C35AD9DF3F316FA1CD41F67393C1E3F4AB5B369046187A30C1A9198ECDC7E71EFD47E35484545DF1E76B30FC6944C0B6D90004F46E9565E35920C44E41EC1BA5565469818A5003FF09EC698890AC903EE53807AEDEF56149980C601C703B56747349012AD929D08EE2A682630B7964831B0CA363BD2B05CBBE647226D67C30E391C83EF5A7E1DF115DF87B5459E165CA7547C94907A6474FA8AC391B77FA420C38E185123078C3E4846EA07F09FF0A2C173E87F0BFC4AB4D4094BC91A3079DB272F1FAFCC3EF2FEBF5AF428E48E6892589D5E371B95D4E430F506BE3DD3B529EC2E53E620A9C8E6BD8FC11E3796CE6315D05FB131CCCA0FFAB6271BD4761FDE51F5A14ADA306AFAA3D868A4565750CAC195864107208F5A5AD080A28A2800A28A2800A28A2800A28A2800A51494A280128A28A0028A28A0028A28A0028A28A0028A28A00291DD63467760AAA32C4F40296B3F5ABE834ED2AE6EEE1808A08DA56CFA0FEB9C63DE93D00F36F8A3E2C9C694D6B6B32DBDBB9D8CA41F36538071FEC8C1E47D33D715E1DF3DCC9F331E7A0EF5A3E21D72EF5CD41A7B876650488E33D14139C5635CCBB104607CC7A9EE6B35AEACD5E9A124925BC2DB51958FAF5A8C5DB2B0DA11BF0A9F4DD1E6BE94048CB13DB15DB5878363441E747BD8F50074A529A45C294A5B1C4F99E728DAA5241E9D2A41E6B0E62FA95EFF00857AADA783ED4A85F2571EB5A71F836CC631101DF359BAC8D96199E31F6372C1A3E327953DEAC7F665CB60B4041038E3835ED0BE09B160410016EE074ABF07846CE188A8E47A11C52F6A2742C784FF00663B22C8C8403C64D46DA534711254943E9FC26BDCE7F075ABC451506D3C81DC1ACFFF00841C213D0AE7D3EF7D69FB50740F14F2D90F03A8C303DE976AA301B7746460D7A9DEF80BF78C5172A0646055393C05232B148C9A7ED513EC19E632C7B485CE71F75BDAB5748D425B69E378D80208EBC8AEA2E7C0572225C0C38EBED5CAEA1A3DEE8D39F3A3207F7BB535352D0995294753E82F869E215D574A92C89C1B7C794A7A85EEA3D81E9EC457755E03F08F561078AA189FFD5CE8F193E84F4FA7231F8D7BF56D17A18496A14514551214514500145145001451450014A29294500251451400514514005145140051451400514514005791FC69D61EDF4FB1D2918ABDD31B89D73CED5E114FB6727F0AF5D1C902BE59F1EEB4DADF8B751BC32168C4A62847A2A9C0FE59FC6A27D8B86F739B4600B3919C0FCAA7D374C6D46E038C919E49F5AA5187B8963B7897259B923D6BD4342D223B3B651B7240F4EA6B3A92E546D469FB4916343D1D2CE2CEDF9ABA6B5B4E4123AF5A4B1B5C95523DEB6238D7B0AE3726CF4D2515616080051C55C8E2C7E3DE9225031C55B54E3B50919C98C58F8A781ED8A78434A0107919AAB117136E78A367183520500F029D8E2AAC4DCAE500ED51B46A3B55964F5A858617247150D14881A08DC608159BAA786AD354B49219630430FCAB558F3D69CB271EB4E3614AEB63C0EEB4EBAF0978A9AD64E064346FCF2339047BD7BEF863C5B6DAEC49138115DEDE9FC3263FBBFE15C3FC4BD086ADA30BB857FD2ED7E6423A91DC579FF833C4F2699A8C4D2B1F2FEEC981CE3D47B8AE984CE3A94CFA728AA5A56A10EA7A7C7710CA2418C33018C9F5FC7AD5DAE839C28A28A0028A28A0028A28A0029452528A004A28A2800A28A2800A28A2800A28A2800A28A280313C61A99D1FC1FAADF23EC923818467B876E063F135F26DD49BA7C0249007FDF55F44FC67B868BC190C2A7026BB5DDEE02935F3BDAC66599E663C29FD6A1EE5AD8DBF0AD8F99A9A36DF963EE7B9F5AF56B2B718500702B88F07DA79AE5C70057A3DAC41556B8EB4AF23D1C2C6D0B97AD6301781C9AB2894C846D5A99783ED592376C9A3241ABD1E0AD514EA0F7AB48FB718AD22CCA68B1B41E29DB062A157E6A40FF4FCAB4BA33B3142F7EB476E94BBBDA9BBB27A629084238A89C0A909E2A17383ED52CB488641935096C1E3A54D230A84F3599A5886ED44D0329E4115E07E26D38E87E25991011139DE9F8F5AF7E90706BCB7E275906582E80F990ED27DAB4A72B4ADDCCAAC6F0F437FE16F8A12DAF63D2EEA4CADD9C44DEADD81FF003DEBD92BE51D2EE5EDC413A64496F2ACA8476E735F52E9F7D16A7A75B5F43FEAEE23120F6CF6AEB83E879F35D4B34514568405145140051451400528A4A5140094514500145145001451450014514500145145007887C69D54CBAE5BE9CAC765B5B6E23B6F7E7F9015E4B68A44078EA6BADF89F76F77F103572321525108FA2A815CFDBAE21403B93591A58EF7C1B1008A3DB9AEF235007D2B86F0683B73F85776831CD71D4F88F4E969045B8F18AB089919A8208D9B1C6055C5D8BC67A7BD42453648910C7153245C6714D4C6719156546056AA262E4C84A1EC28C107A55B007B505148C815A720B9CACA48EB4D63F9D58D80F03141840C52E563E6457C12290C79AB2540A8CE31CD4B882914DD315011CE4D5D7E7355996B26B53452216C115C478F625934975C65BB576CFC5713E386FF00896B8EFDA85BA097C2CF32D381DA14746054E7D8D7BD7C2AD48DE7851AD1DF2F6729403D14F23F5CD782AFFA35B893241F3011F88AF50F8437E135EBBB407E4B9B7DE33EAA47F426BB63B9E6CB63D8E8A28AD8C828A28A0028A28A0029452528A004A28A2800A28A2800A28A2800A28A2800A28A2803E62F8951087C7FAE6063F7C08FAB006B06DC816A093CF35D1FC5424F8F356C83933A819F408B5CC4583005EF9AC99A23D1BC19FF001EC0E39CF35DDC2BBD87A570DE0A42F66A7DFAD7758658895E1BD6B8E5F133D283F710EBBD452D94C7102F2770BDBEB58CD3DEBCA658A399971D00C66B4EDECBE6DC0EECF527BD6B430C11A65880A393934E2BB8DCADB1C98D6EEA39B63298703952A49A58BC4F7F04A04DB8C67A315E3F1AE96E758D0D0849AFED432F6F30122AACD79A3CC02895006E465700D53B74145DF7458B2D7FCF452CB82C3B56B4773E62E41AE5E58238FE687057B62B4B4EBA050293ED494D8E54D5AE8DC0D81B8F7E94D79F6A73D052647979CF359B7B3EC8B1DEAA53B19A8DD9625D4A1894963D3AD64DC78BAC230427CCDD3D6AABD8BDE29123E14FAD25B785B4EDFB9A4CB7A16E951CCD9A38463B8DFF0084B239064201ED4B078844F36CDBD3AE78ABA9E0DD295CC811998F5CB714B3F87AD1147930AA6DE4629B892A6B62D330740CBD08AE2BC6CB9D35F9C135D3596FB794DBC99D8DCA9F43E95CDF8F976E8F2B7A63F9D42DD0DE89A3C9F5090ADB40A7AB499FC2BD0BE12AEEF17DB64E365B3903F0AF3CBEC32D99EB8E48AF47F83C86EBC6534C14797059B11EC4903FC6BB5743CE7D4F73A28A2B5320A28A2800A28A2800A51494A280128A28A0028A28A0028A28A0028A28A0028A28A00F9F7E3469A6DFC671DC7245EC2AE3D8AFCA7F97EB5C1C49F291D81FCEBD3FE2EDD26A7736D2C6EAE2D77A851D403DFF00315E796F092625E4EF7FE558F3A7B1BBA72834A47A8F82EC8C3A4C6C47279AEA88079C671DAA8E8F08B6D2E18F1D1055A30866CE07E55C5296A7A118E962A6A9AC0D3ACFF75099676E12251924D7137FA7F88F5EB5B89B51927B7E3315B47C291EF5E8B0D8C68776C279CF1D5AAD84509F7703FBACBC5383B6E124AD647885AE93796EA206D31CAEEC991A3249EBC7A735E856BA5DAD9F87AD4249E5DD85CCA814B29F63EE2BAC658CF1B500CE78CD4125BC1C928315B395D58CE314A5CC73902ABC2DE5BB473852C114E41FF0AB7612BACF116EAC39FAD5C91460A43C023E638E83DAAB4087ED4840E178158CB7B1D4B53A549098C0E2B1EFE461305E3D066B522271D6B3AFD7372983834A5B1115A983A85C933790B2B48E78C29DAA3EA6B9BF1035FE93A840A2F41B574DCFF67C027D831C9AEFBECD14ED9740ADDF1C66AC8B0B7600490A381D03006B485B726ABE6D0F2FB2D675E96F9174BD4E658E473B52E083F28EEDD715D3E99E3C963BDFECFD66DCC72E7689907C8DEF5D545A4D82E76DAC60E739E29B7BA4D9DCC4639218F6FA003344E48CE2927A9332A4C56442083CF06B9AF1EDB97F0EDCB019C2D741696CD664448DF201819EC2AA78920FB57876F62C6498CE2B38BD47256D8F9FAF59B108EC11715EAFF0411BFB5753720FFC7B800E3FDB15E65730868ADF079008FCABDE3E137874693E184D42420CF7EA1F8FE1404E07F5AEE8EACF3A477D451456A66145145001451450014A2929450025145140051451400514514005145140053263B6090FA29FE54FA8AE7FE3D66FF71BF952635B9E49E23D363BBD36750BF300C49AE074887CED5AC62EC0D7AD3DBECB09A771BBCCC9C7A03D2BCE34487678AC8DA42C6481ED9AE24EC9A3D6C42E69C59E9F08022503A01C55A8B008F535562FB8335617839AC5948BC98039A4765CE0134D8D59BAF6A9C460AF4156913A22990CEDF2834BF675032D93577C9E7DA94A0C1E00ABE5072EC645C2F1B40FCAAB471E2451D31E953DD5CA6F644E48EB51DB2316DCFC13DAB37B9B2BA46AC43E5EBDAA8DF27EF15BB568C3165338ED515D4584208AA71D084D5CA9182782335602100E18D47692AABF9520E3B1AD45851B907F2A515714DD999F8607E6E7E82A64DAD9C60D58680E781513463B7047A537168574C6141CE4556B98F7DACB1766523F4AB2CD8E33F8D44DD718EB59ADC867855AD83DDEAB1DA2004B4A463D81C1FD2BDFBC213A1D30DA22145B7014293D3B7F4AF29F0C5929F175E1E71049264FA64D7ABF8517F7133FF78E7F535D506F9D2339538AC3CA4F7B9D0D14515D479C145145001451450014A29294500251451400514514005145140051451400535D3CC8DD0FF1291F9D3A8A00F3EBAB8F95AD597231B6B8F4B3FB3789E2754DB1CA060F5C15EBFCEBD0F52B0824D5E50D1F0ADB87E3CD624FA7F977EB21036A9CA0FEB5E7BBA7667B32946704D7A97630401C5581512F0054919C9ACDEE28B2F44700135723C7B5504600558127191D6B5831495C9A595546011CD50BAB9DB048C3A81493CD96DA0F350C830A549EBC1A6E772A3048AD6DE5470F9923282464926A05D52D2698A5ADD452B2FDE54704D23DA15F9762CF1F64638C5645D787ECA6B9FB54109B7BA439568CE39ACCDAC9EB73BC86E63FB2C7800311CD41A8DC471C439193EBDBDEB9D4BD9D618D7692CBF7A96E54DF6D697718D7FE599E327DFDAA9D46D58C552D6E68C135B4F1931CC8E41E769CD68432B0406B120B1557F336C716472B18EBF5AD34CEC233CF6A94EC54E28D38A40E9D71448063B66B3ADA7C3956386156DA5C826B572BA3271B3229463E95093FBC19F5A7C8F9A87AB0158F507B1CDF84F4F293EAD7520C1B8BA62B91FC3935DFE876FE458938C076C8FA7F9CD7190DD3C33982304E093D2BBFB3564B2815B8608335D346CE4D99E2D3A74947B93D14515D479A145145001451450014A292945002514514005145140051451400514514005145140181AD109A821C632832477E6B12FB9B98BDD4E6BABD4B4EFB6857460B2A7033D08F435CF6A3A75EC2F1CAF6FF00BB4C86752081F5AE5A907CCD9E851A90704AFA9507414FCFA77A8C1F996A6C6074AE496E744762CC2011ED53380919CFE150C1D053EE01DA31D68520DD9573B14B100B13C9A89E6C92481D68951B6E4E460679AAAB20DC4B3F51DE9DCD3726CB6E38E4FA7A52471BC8E30BB4F7CD466E23FEF73DEACC534783CB608F5AA516C1A63F728382A188EE6A09449B738C96FCE9B27D97EFE589FF007A9C2E63098FCB34DC243507B91C45C939247D0D5A490AB28CFE354DAE602321B07D29D14A92B80A6A354368BD38257CD4E5D7F5A9A19FCC881031EC6848999001D31447179701DDCF3DA8E633BA6AC46CD938F5A72FDE3DE88937483FD919A338622927EF112D8B36D6F1CB7702EC041619E3F1AE9AB9DD2D8A6A51A9E7208FD2BA2AEFA0BDD38B177E7498514515B1CA145145001451450014A2929450025145140051451400514514005145140051451400541789E658CE9D731B7F2A9E8A011E7F9F9B8EB572325B150DE43F67BF9A2C7DC738CFA76A58240C40CF23A8AF2E71B33D783BC6E5B806D18F7AB650B019AAA061855E8CFC9C524852672FE287D422457B5E235E5801D6AADB68D7F73134BF6E5703691B57AE7AFE55D2DF0EA48C8C60E7D2B9C669F4E95CDB48446DCED3574F9766691E669723B337A3F0920B8883DC48F191CF6E6AEC1E1784DCC8BBA50A318F98F354ECFC4EB3BC21D3CAC0C12790C7EBDABA3B6BB6688CADB7040C6C39AE9518F439AA55C44349192DE19B737423DD273CFDEE31531F0C59A5C20F2CB260E77126B504F9973B0F03AD51D575836908749225653CAC8092C3D0629D910ABD693514CA177E18B4304DB536313F2107A570DA86997367AC35B59DE3C8CC385EA14D74979E24BA9ACCC512E1D9B265C6D38CFA547A3DA6C2D7329DD2B9FBC6B19B8A3B29C6B4173547F2356C2D9EDED63576DD26D0093DCD589942C6062A44E82A2B87CE7DAB07B195EEC860036C8C7D71459422E6F16324856EA475C5337058B1EBCD5ED0E3DD73249FDD5C7E26AA8C79A689AB2E5836695A6990D9B99159DE4E9B9CF415728A2BD2492D11E74A4E4EF2614514532428A28A0028A28A0029452528A004A28A2800A28A2800A28A2800A28A2800A28A2800A28A28039AF135B18DE3BC45E1BE490FA1EC6B120601F23B8AED7548567D2AEA3619FDD923EA3915E7D04C164C13D3D6B8EBC75B9DD869E9666EAFCCBCF5AB314BB545508240CA79071522B9E45729D0D166750EA7D0D65C96E1B28466B495C15C30CF6A6B202D914D15176461AD83C527AA75C7A569C114B1A1F227703FBB9C7E9569610DD7AD35E0639033C77ADE32B22DD6BAB4861B9D4241CCCEBC609500715464B68F2C6526473F89ABC23988032187B76A992D72727A5539F9046A463B7E06341605DC3B8DAA3A2D6AC2BB48006054ED1AA800520E0F15CF27A932A8E7AB2756C2D57958B71EBD6A4270951310AA49EB506688A66C0DB918AE8749B73058A9618793E66FE9FA5626996BF6FBDC9FF53110CFE84F615D4D76E1A165CCCE5C4CFECA0A28A2BA8E40A28A2800A28A2800A28A2800A51494A280128A28A0028A28A0028A28A0028A28A0028A28A0028A28A0064EBBADE55F5461FA579A5C407EFA1C30EF5E9AC32A47A8AF3ED9918C77C573623A1D78657B95AD2F46423707BE6B4BCC19045645CDB9DDB9090DD8D4715F151B64241E9CD7234759D086CE304559519158305F7EF3048DAA339F5AD7B5B859A3C8239F4A2C3B96D1950F5FAD48D2A1E322A011EF0769A745096E0F03EB571B834B726DC9C6318A0C800EB4184636D46D1ED18269BB92921ACC18F06A189A4676F300001C2FB8A460E24181F281C9A8A7B958863F88F02B268B7648B06404E73C0AA57373B80033ED8EB51CB73B1319F98D3614DC771E49A496A458E97C36BB6CE6E724B8273F4AD9AC8F0F9FF469C7A38FE55AF5E952F811E756569B0A28A2B4330A28A2800A28A2800A28A2800A51494A280128A28A0028A28A0028A28A0028A28A0028A28A0028A2A1BCBB86C6CA6BB9D82C50A1763EC280399F1CF8CA2F0B69DB61DAFA84C0F9687A20FEF1FE9591632F9D04726721D0367EA335E4DE28D62E35AD62EAF2E1B2EFD17B2827803E8057A2784EEBED5E1DB17DD9611053F51C5736236475E13768D9962CF38ED599756BB8671C8F4ADCC6E5E955A6871D338AE53AD9CBCE92A11E8390DDC55BD3B57F298473101B3C62AFCF6CAE318CD62DDE9ED13E42165EA41A6990F4D51D859EA28FC123F3AD486E623800F26BCD2192488E239DA33FDC93A568C1AB5EC6B8F2C330EEA69A9587A33BE69541E587355E796319F9BA7415C87F6DEA2E9810AEEF76A824BBBB646134EAA7D23E48FCE872B8F447437FABC709F2E3F99CF1B456524CE5CC8F9F309FBA0F4AA96D1B48F98D0EE3D647EB8AD6B5B355009EB50D8D216084C982C38EC2B436630288A221B3DAA57C2D24522383C476FA15EDBC17785B7BB72A65FF009E6C3A13EDEB5DA672320E41EF5E25F102E04726991E7EF3393F4C015DAFC35F1136A9A39D3AE1CB5C5A0F9198F2F1F41F974FCABBE8BF711E76257EF19DC514515B180514514005145140051451400528A4A5140094514500145145001451450014514500145148EEB1A1791951072598E00FC68016BC9FC79E2BFED367D3ECE4FF00428DB0CE3FE5AB7F80ED5A3E36F1AA3A3E97A54C19586279D0F07FD953E9EA6BCDA42197A8E7D6901CEDC125AE0E73F3819FA0FF00EBD775F0D2F849677762C7E689F7AFFBADFF00D715C03BE4DD0F4909AD5F06EA8BA6788A2676C473298DF3EFD2B2AAAF166F425CB347B745D3A734AF186078E2A382459143035615782C3F2AE24CF4199CE9863C7D29862126411C8F5AB73A1249039A85305C714EC4B332EB464946E518359ADA2DD21F91C81D706BB48911D7A0AB1F654206467EB4D23367111E8B76EBF3C9B7DEB42D7C3F1A00CE4BB1EE6BA836C00C019A6B461171D0D26868CE8ED123F976E3F0A9634F98E0F3529EB5246BE9516344204DA09A89CE6AC13CD65EAF7F0E9D632DCCCDB52352C4D32E279AFC42BE137896D6D94E45BC596FAB1CFF002029BE17D667D175E1750B0CC6F8656E8CAC3915CA4F7B2EA5AB4F7B2FDF9A4DD8F41D87E55A36AE3FB4255EA4A822BBE9C6D148F2EB4B9A6DA3E94D2757B4D6ACFED16AFD3878CFDE43E87FC6AFD784691AF5DE8B791DDDABE0E00743F75C7A1AF58D1FC63A4EAC91AF9EB6F70C398A538E7D01E86B43237E8A28A60145145001451450014A2929450025145140051451400514557BEBFB4D36DCDC5EDC470443F89CE33F4F5A00B155AF750B4D36033DEDC47047EAE7AFD07535E7FAEFC50DBBA1D1A0F6F3E71FC97FC6BCEB51D56FB529DA7BCB996690F763FE71480F4AD6FE28C30068F4AB6DE738F3A6E9F50BFE35C2EA1E24D4B5B72F7B7724880F11E70B9F6038AC02C40F5278AB200450BE9D7EB400F3212DC9FAD34E09F5A3273FE1428DE4E28039890E2FAE93D4D537CAB706AD6A07CBD5A418E180355A5033C5203D17C11E3500A69DA8BE18E16299BBFB1F7AF4E8A50CBC57CD0A4839AF4AF04F8DFE68F4DD4E5E7858A66EFF00EC9FF1AE6AB4BAA3B68D6BFBB23D464019491F7AA9104B607153F99C0C74A4C073D7E9581D16085BCB6C1EF5A50CA081CD515418C1E0FA1A9150A9E0D589D997DDC01559C9639A728247CC734BD3A0C527A896840D1E0824FE14A3273C53DBDCD4324A154F350CB4C259022939E71F957947C46D6CCCF1E9B1BFCA4EF900F4EC2BB0F12F88A0D26C9E495B2C461133CB1AF17BCBB9350BD96E66399246C9F6F6AD68D3BBB9957A9C91E5EAC2DC61C35685930FED5EBD63AA5180800A9B4F707598C632769AEC479E744AC36E29E92100AB72A6A1604673CF34A0F1914C4741A478BF59D1088E1BB3242BFF002C66F9971FD3F0AEFB48F891A6DE6D8F5089ACE4EEE3E7427F98AF2224B019E48A5538638FAD007D1B6F7305DC2B35B4C9344DD1E36C8A92BE7FD3B59BDD3271359DC490B772A783F51DEBBED17E24872B16AD08F4F3A11FCD7FC2981E854556B2D42CF5287CDB3B88E65EFB4F23EA3A8AB3400528A4A5140094557BCBEB4D3E0335E5C470460672ED8CFD077FC2B88D5BE27DA405A3D2ED8CEDDA59BE55FC0753FA5007A063358DAAF8A747D1C1173788D28FF96317CEFF0090E9F8D790EA9E31D6F562CB35F3A45DE387E45FD3AFE35866407D7DCD203BFD5FE27DE4BB934DB74B64E81DFE773FD07EB5C35F6A577A8CED71773CB34A7BC8C4FF00FAAAAE79CF34BB7D7AF5C668018DC1CF3ED4C2C718E2A6231C541236073D3DA9804403CB93C85AB180467144516D8957B9EB52140383EBDA9011E4820D390F5EF4D3F4A72F0076E7AD3039AD7E331DFC72606186335473915B7E248F75BA3839DA7358719040A402ED04533186E73528EB4D71C5033BDF08F8E9AD82586AB21687858A76EABECDEDEF5E9D0CCB22875604119041CE457CE238AEAFC2DE32B8D15D6DEE0B4D624F4EAD1FBAFF0085615297589D54ABF491EE11B2BAFCD532A7A1CD62586A905E5BA5C5BCAB2C520CAB29AD14BA0C301856074DBB1780E3A5359F02AAB5D85E335565BC2C719C0A4C39596259B1F2E79AE7BC45E22B6D16C9A5998173C2203CB1AA1E22F16DAE871329224BA23E5881E7F1F415E4DA96A575AADDB5CDDC85DCF41D947A0ABA74DCBD08A95953D16E3F54D56E758BE6BABA7C93F757B20F4155E250324D44064D585C05E2BA924B4381B7277623310BD79A4D224275C8FF00DD34D90D3B4319D710F600D52133AB93B64F3D3EB4C1D31C5492A9CFA1FAD464118EA4D021EB81D4FD3141CF3D7E948A71C8A7F5E707F9D30101E3A54884AF538C5443E623B0EE2941C938CD0068D95FDC59CAB35B4EF14ABD1D1B06BBBD1FE23CABB62D521128FF009EB1E037E23A1FD2BCD94E39C1C83EB4A84EEE01F5CD007BFE9FADE9DAA28369751BB1FF009664E1C7E06B42BE7A8AEA488AF278E841E47D2BA8B1F1A6B105B08C5F160A78F31031C7D4F3401C96A3A85DDFDD34B757124B21272CEC4E2A9E3279A795F9DB8E734D0B8F4CD201BB4038F5A5038F5A7E0000E38F7EB4D0A3A5001B79C76EF9A7E79271903DE8EF8DB8FEB48DC28C1F7A6031987F09FAD44AA659BB155E695DB0BEF4FB6DA611B48627EF7B1A009C201D40A6139CE69E5C0E00E2A2273C2F3400BB739EB4A7E5200E4D359B6FCA0FCDFC8D3118904E39CF5A008354877E9F271CE0D72509E0576D7196818631C57158DB23AFA3114809FB6690F22914F6341A061B734DC62A40334A40C50069E85E23BDD06E7740DBE163FBC858FCADF4F43EF5EBDA26B567AE588B9B490F1C3C7FC487D0D78601CE6AD58EA779A45D19ECA53148CBB4FA11EF594E9A96A8DA95671D1EC7B95DDFDB58C465BAB88E251FC523015C1F887C7E8375BE93F331E0CEC381F415C8DA69FACF8AF50710CCB7572ABBFCB7994311FEC8279FC2A8CB6EF04EF14A312236D61E84528D14B5654F10DE911B2CB2DCCAD34CED248C72598E49A455C9A52B838A78E0715AD8E76C5D985E3AD0A7029493D0D340E4E78A00639C8AB1A0A13AA338C12077AAED57BC3F9FB5CDF85342674B229607A54382B8CF03D2AC331278E83F5A8D86E3D00EF4C045C0C8E9ED4A3078C9C7D690F3DB38A453EF8FC2801AC304B7AD3C13C1E31EF43ED452EE7FFAF446498F0463B8E6801C011DFA76A7024F503EB9A400B2F2C73DE973C8C76F5A600783CD5AB771E59C9E73E95588E84F39F6A9635F94E01C669010151BC9C9EA69303271CE3BD3E4FF005878C60D373B718EB9EB400846072700D03AF3CFB52B0C9A5238DDC73C50034E7B6334D7C91D31CFA53BD7814C276FCB9FA8A0444E85B8C702A9CA92452F99136D6EFE87EB578B82085E49ED4C16ECE4971B47EB40C8E0BE49DB6C8BE5C9E98E0FD2ACFDE3F2F029C96D146095500F73D4D03D01C50044460F149820E31C1A7B0DC4E3814CCF1C75068026C62220F5C57177236DF4C3FDA26BB55CB752335C86A6BB354947AE08A1810A9E29D4D51C53C5200CE0D3B19EB49DEA7B5B59AF2EA2B5B7469269582A2A8C924D004124B15BED79559D370CAA9C16F500D76E60F08F8CECE38F4EB74D37548D00007064FF007933F31F7539F6ABF73F0F6CA1D323B7D76DA6B19C1222D5AD2433C2D9ED2276FC307DAB87D7FC19AB786CC77132A4F6321FDCDFDAB6E89FD391F74FB1C1A1810EB1E1DD5FC38EB3CF62A210DF25DC0C5933F51F74FB1C1AB177E29BBD7EDE34D4EDA396EE20156F106D91C7A3FF0078FBF5AEA7C21E319622B61AF3FDA2D241B3ED122EF641E920FF00968BF5E4763573C59E04B7D3617D6348402D061A7815B70881E8E87BC67F4A4981E7FC30F7A403079A8DEE10DD6DE81BA7D6A43CB7BFA5318A4934DC734E1C76A0F5E280227E957BC387FD22E0919C11546438539ABFE1AFF59367B9142133A4241FE1C7A5386DE724629A78207A0CD1C6C231DFB5301E7681918FA546ECA8A18E001D4D3B04F7E00CD38283C7502988CF25AE640EC708BF747F5AB6140DA41A468003B97AFA53C71C1EB40C78072401C9F5A41EFD0D286E8476EE69AD8248273E94002918273CD5A831B09C1E4F6AAC09CE7F954D1394523DFD280227F99C8F7CE6A323E61EE6A4707CC3EB9ED4D66032768E29084E7248E94A464918E075A14719FC69369C1386FF001A603791D8FD7AD4172E5636DA7E603AD4CD9E80F1EF50CA01041E9DE8027B765F2D766002323DEA5EE723B67154AC0E6231FF00CF3623FC2AF01D0AE2801802AE79C64669833D0726A5DBB739C533A9A008882783834D00027207E34E627A74151A8049EB8F6A432CA9C6707A7A5727AEAECD490FF796BA98BDFA0F5AE73C509B25865039068623354F14F14C4C15C8E98CD380E47AD218F5F7AB7A5EADA769BAAC7F6F4BB2A4644B6920592139E187AFD38AA6D88D0B9E83F53E95962D24B9B96D873331C853FC5EC3DE803E8AD1BC5727D83ED32CE9ACE92DF2BDEC0BFBC8FDA68CF5FC7F3AD88F45B596DDEF3427866B2BA189EC5BE6B79C77001FBADEC79F4AF9B346D6752F0FEA02EB4FB892DEE17861D98775653C11EC6BDAFC09E28B2D76E0C9A704B0D5587FA56984FEE6E40EAF17A1EF8EA3B509EA339FF17F82D7458CEA9A6A3FF67B361E26E5AD98F63EABE869FE03F16E66FEC1BCC488EAC2D83F46047CD09FF658671E86BD635158EF2CE46110994A149A16FF00968BDD4FB8F5AF9BFC5FA5CBE15F1029B5998DBB91716530EBB73C7E208C1FA5262454F18E93FD83E269ECE125AD89135BB1EF1B723F2E9F8555B39FCD8C17FBE3EF7BD69F8C7598F5FD52DAE23006D814311D99BE623F024D62A298B6BAF51DBD685B0CD23EB8A43C669A8E2440C0F07A539A98114C32BC77AD1F0E1C4D3301E959B3B6067D0715A7E1A18926CF6C53423A323058F7C518C8C91CD2838EF9CF34E61C6473EB40840ADB724D19EA470691D84519627E526A38EE637182E37771D29812FF00C0BDA9B83CE453B8EDF8D200318A0069C28EF4BF771807DE9922E5003EB5230F90F3C50319B8EFE01E956603FBBEBDEAB36401F313562023CBFBB9E680226FBCDC73BBA537664E4FD49A7BF32301EB4857FBBD7340814718C72280C40E690E71D7927AD213C633400D3B8609A8A4C7271D7F954A4823FF00AD4C2BFBBCE68029DB1F2EF4AF389173D7B8AD34E87273E959736E8E58A4C7DD6F4ED5A48C3B66801EC3907B9EB4C619241CE4F6A5E7A9E39A46E79CD0042CBCEDC8A4C90411DBB629597E6240F6CD20E09CF1DF34864919E08C561F899736E9EA1AB701F907F4ACBF10A03A7B1C64820D0C47356A7E4C1EDC558C1C8C753D2A9C1F7F6FF7B8AB723145F2C6379E0FB0A432299B7B051F717F53EB558AFEF1707073C1F4AB2DF2AD57670A771ED401D55868C3C656412C87FC4E605DD264610A0E3E76EC7D0F7E95662F00F89746BC59844AB3429E7978A603C90A32599891B715E9DF0E3458347F0B5BCB082D737C05C3BB8DBDB8273D140E99FAD721E3FF00170D5125D1F4B90FF6786FDFCE3ADD30FF00D90761DFAD16B01BDE0FF88B17885DE19891A9C3117940181728BD580ECE3AFBD711F142E6DEE6EE0B78195E32FF006984AF40AE3E603DB2335CFF00867C3F75AD7886382D9DA1863FDE5CDC02408A21F78923D4718EE4E2B47C796B0597898410487CBF215920239B75249543EF8C1FC6A7A8CE6228BA7153B28C6295050E302A84471B7932609F909FC8FAD5F1C8CD51601D0D49693160626E5D4617DC50319390C5547739FC2B6BC383E6B8F6C561B7339EF8E056EF8748F3E6EDC8A6846F76E3D297B6724629C7AF07826800007DB8E9408301D406C1F6AAD25946C72B953E839156D07209A42C7711C7E069814A34B8B77009CC6474CE7FFD5568005471D7BD48DCB6D3E9C7151B282DDB8F7A006CA732A28E78A776C1CE4531FF00D7E31C8C54A41241A0631BE5233DEA6B70BE59C8EFDEA171EC01A920E10F04F3400A48DE727B9E94600E074A523058E463A5260123BD0211B1C01CD31BAF00600A71197E69B8DC4F031D28019C8E08C5249D38E7F0A7E7AD46C7E6A00AD7281D1947A75A9ADDC3DBA311CE39A57518F5A82DBE5DF1E790723E86802E9248CF149D88A542186D34857D0FE740119DA3193C8F4A69EBDB03D2A42AB9FAF7A43C76EA3E94862A803E53DCD53D690BE972F6C0AB8A7902A2BF8F759CAA73F74D023854FBD56630076AACA306AC4679A43125E168D32C5F55D6ACEC1012679557819EA69B3B002BB4D363B7F08E8B0EA1E403ADDD022191CFCD0E47551DB0A7AF5C91401D678F3C522D206F0F6992004288EF2643D80C794BEC3BFE55C3691A3DDEBDA8C5A7D8C7BA693A93C2A2F7663D80A8E1B5B8D42F22B6B789E6B899C2A22F2598D7B069D61A57C3FF000BCF7178EB230C7DAA543CDCCBD44319FEE8EE7F1A00CAD565D23E1C7851520559A490E61571F35ECC3FE5A3FF00D335EC3FFAF5E2134F737F753DFDCBBCB2CB2169256EEC79AD2F156BF7BE24D665D46F9C176F95117EEC483A228F415D55A78705AF80B51374A5654B64BA718E56466CA29FF80E0FE353D467131F4A7B2FCA69919E01A95CE56A845743DA865039EF401F352C9400D8979F6ADFF0EE049393D320561C43835BDE1D1CCE7FDAA680DD23278071480F5F989A7E7E5383CD346319FE54085191CFEA29C76F427F1C528E3A372074C500E7B649E6980CC64920D20C93806970A48CF514050791F8500349CCAE47AF6A9368DA33DBAD44BC8CE39CFE15229E79C508631B19C63247AD4B0E761E40E6A27C1239E4FAD490950878CF3D85021E48F9BA75A418DDD3927348E36330A07098E33FCA8108D819E73ED51139240E062A46C6083CE2A238CFB1340C71238A6E3739078ED4A70070793403C640CD0046E00380411F4AAA0EDBBF665C67DEAE119C6073DCD54B8182AE3A86CD005A46E29DC670BDF9A895883CF3F5A99946CDD9E4D003581C8E7EB4D6E00C76E94EE0AE29A4E78E82800CED26A4917CC84E0678EF50F7F71D7356010613CE7B62803CF241B6575F4635345CF4A4BE5297B3A91D1CD1074A919A9A0E9E351D7ADE2750D1A1F31C762179C1F6CE3F5A8F58D58EADAF3488E5A08FF7711FEF0CF2DF89C9FCA8B5D44596997B1404FDAAEB1133FF00722EA40F763C7D07BD75DF0CBC286E6F63D6AE60591124D9650B8F96494725DBFD841C9F7C500773E0BF0E47E1DD31F53D49960BD6877CD230FF008F3848E9FF005D1BD3A8CE2BCFFC6BE2697C45A80601A1B1B7CA5AC19E157FBC7D58F735B9E33F152EAD31D2B4F99A4D3E172D2CDDEEA5EEE7FD91D87E35CE68FE1EB9F126B096301F2D00DF3CCC3E58631D58FF004F534010F843C3D1DF5CCBACEA3116D2EC181F2CFF00CBCCDFC310F5F56F6FAD7A6EA3666DB47B6B5D4486B9D46F04F780F655F9DC7D00551F9D6CE95A3DA2A5BB451AC1A4E9C08B4493A330FBD33FA9EE7DF02B86F1DEBE1747BCD4C92AD7AAD61A6C6C7E61167F7B29FAF4CFAB1F4A9921A3CACDC2DC4D24C8A111DD9828E8A09C81521E56B3ED8E015F4ABE394AA02303E6A24E4D0A79A6B1CB714089A3C05ADDF0E6364FC7F17F4AC3C6D415BBE1B03C894F425C8CE69A036CE0F6FA8A41F7BDA9CD95071D33C1A0025FD47AD0217DF278A3E600B0C71C53874E7A534819E99CF4A6023678CFA7A51850BDB03D0D047CE383F4CD237DC73EDD31400C5C989724FD314E52320FAD391405C1FAD38631C0C9A008D946086C023A54909DA8402719F5A6363A93D78E29D1AE54F03AD003DF3E6373819A69CB71C648E6948667386EFDA9A46E272706810D6CF7C1A839278FC2A7700707A8AAA3396CFAD0344E010B818E98E690718073CF7A45CB70453F8CF4C6D1400C0700E1AA3957CC47E3B75A9362E3D0FA5211CE07208E68020B7625149EBD2AC8E4118E2ABC6A04AEA7D7233DAACAF5DB9E9400D38048E9CFA534F390339A7F439033EF48E39CD0033EF718A9A305931C0CD440F3935221C92391480E27594F2F559C0E84E6A0B7FB9577C40BB7546F75154A004C3C024F603BD219AFE18D0A4D7F54FB386F2E05CC97136388A31D4FD7B0F52457A1F8C35C8F42D31742D3904171342239114F36B6DD562FF7DBAB7D7DE974D8AD7C07E0D5B899524BC720953FF2DEE7190BFEE479C9F56AF3B334F7D772DCDCC8D2CF3397776E4B313480D1D22C6E350BC86CED2232CF336C4403A9AF6FD0BC356FA4E9BFD9B036EC90F7D72A3995FB2AFB0E807E359BE07F0A1D0AC84B3A0FED6BA8F2FBB8FB34479DBEC48E4FA74AEBE666B78520B407CE7E221DC67AB9F73DBD055A4230FC437313C52D81996D74FB64F32FE71F7628D7A20F5F4F7635F3C78B7C40FE24D71EEFCBF26D63510DA41DA2887DD1F5EE7DC9AED3E2378A23BACE83A5CBBACA19375CCEA7FE3E651FFB2AF6F5EB5CEF81BC2BFF000926BC0DCA37F665A625BB61FC433F2C63DD8F1F4C9A8651B29E15165F08DEFE6091DCCD2A5E3B38F98467E48D07B9C96C7B8AE290FCB8AEF7E2EF88775D41E1D81940B7713DE04FBBE6E30B18F645E3EA6BCFE13914201A38269ABCBFE34BD18D2C3CB5311331C0ADEF0E28FB2B9238DE6B9F73D6BA2F0E7FC79F4FE2269A066CE4AAE07AD19DAD8007F8D07248C77ED40C9C93802810E0CD827B76E28182016EA29491B7078E7AE681C7BD30180E5BF1FC6924394E4F538E6970093914C906022E3BF7A009768C06639FA5203B72DB4E29FD62E3191E948589EA7B7A50046572CC1781EF52C0008F9F5F5A898ED20E39FAD4F06761FAD3026F29031C2F7A1E240385EB451480AF2C69B41C738F5A8C449FDDEF451400F4893238EDEB4796BB18E3B8EF451400EF2D3D283126FE9FAD145022BBC482E970BDAA648931D3F5A28A062BC4983F2F6A431271C7EB451400C1121DD91D3DE9E235DDD28A2901CC789608FF00B414EDE76FA9AA365122AC6CA3043020E7DE8A290CECBC7A4BF8896D589305B5B44B0A678405431FCC9249AB5F0D6C2D6E3C5B69E742B208D1E550DC80CA09071DF07D68A2840CF6BD3544912BBFCCD2CD8727F88019C1FC6B9EF175D4F0783F55BA8A5649DD9223203CED638600F6C8A28AB7D40F03B8823C9F97F5AF6CF03DAC1A7F81B4E92D6258DDEDEE2ED88E774CB9018E7AE0018ED451598CF9FAE07DA6692798B492C8C5DDD9892C4F249AB56D0C7B47CBDBD68A2840C6B431E4FCBFAD3E1823DDF77F5A28A6215A18F27E5FD6BA4F0FC118B0FBBFC47BFBD1450819AFE5261BE5EFEB48224C0F97F5A28A62078D42A8C7BF5A72C498FBB4514C00429B54EDE49E6A19517ED0463A5145004BE5260F1FAD46635C118FD68A2980890C67AAF7F5AB1046BB5B8FE2A28A00FFD9";
InputStream is = new ByteArrayInputStream(hexStringToByteArray(photo.substring(2)));
FileOutputStream out = new FileOutputStream("/home/bmartel/test.jpg");
byte[] data = new byte[1024];
int readBytes = 0;
while ((readBytes = is.read(data)) > 0) {
out.write(data, 0, readBytes);
}
out.flush();
out.close();
is.close();
} catch (IOException e) {
e.printStackTrace();
}
With hexStringToByteArray picked here :
public static byte[] hexStringToByteArray(String s) {
int len = s.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
+ Character.digit(s.charAt(i + 1), 16));
System.out.print(data[i / 2] & 0xFF);
System.out.print(" ");
}
return data;
}
For Base64 data use :
Base64 base64 = new Base64();
byte[] data = base64.decode(photo);

Convert Java MessageDigest code snippet to C#

The java code below generates a SHA-256 hash of the input msg, using the key. However, all my attempts to write code that does same operation in C# have not yielded the same results given same input. I would need help getting the C# equivalent as I have tried a lot already with little success.
I think I've been able to translate most of the code into C# correctly, apart from the part which updates the digest (m.update()), first with the key, then later with the message before hashing.
JAVA CODE
public static String generateHash256Value(String msg, String key) {
MessageDigest m = null;
String hashText = null;
System.out.println("Value to hash::::::::::" + msg);
byte[] actualKeyBytes = HexToByte(secret_key);
try {
m = MessageDigest.getInstance("SHA-256");
m.update(actualKeyBytes, 0, actualKeyBytes.length);
try {
m.update(msg.getBytes("UTF-8"), 0, msg.length());
}
catch (UnsupportedEncodingException ex) {
ex.printStackTrace();
}
hashText = new BigInteger(1, m.digest()).toString(16);
if (hashText.length() < 64) { //must be 64 in length
int numberOfZeroes = 64 - hashText.length();
String zeroes = "";
for (int i = 0; i < numberOfZeroes; i++) {
zeroes = zeroes + "0";
}
hashText = zeroes + hashText;
}
}
catch (NoSuchAlgorithmException ex) {
ex.printStackTrace();
}
hashText = hashText.toUpperCase();
return hashText;
}
public static byte[] hex2Byte(String str) {
byte[] bytes = new byte[str.length() / 2];
for (int i = 0; i < bytes.length; i++) {
bytes[i] = (byte) Integer
.parseInt(str.substring(2 * i, 2 * i + 2), 16);
}
return bytes;
}
C# CODE (attempt)
private static string DoSpecialSha256Hash(string message, string key)
{
String hashText = null;
Console.WriteLine("Value to hash::::::::::" + message);
byte[] keyByte = hex2Byte(key);
Encoding encoder = new System.Text.UTF8Encoding();
var hashAlgo = new SHA256Managed();
var messageBytes = encoder.GetBytes(message);
var toDigest = Combine(keyByte, messageBytes);
hashText = ByteToString(hashAlgo.ComputeHash(toDigest, 0, message.Length));
if (hashText.Length < 64)
{ //must be 64 in length
int numberOfZeroes = 64 - hashText.Length;
String zeroes = "";
for (int i = 0; i < numberOfZeroes; i++)
{
zeroes = zeroes + "0";
}
hashText = zeroes + hashText;
}
hashText = hashText.ToUpper();
return hashText;
}
public static byte[] HexToByte(String hex)
{
return Enumerable.Range(0, hex.Length)
.Where(x => x % 2 == 0)
.Select(x => Convert.ToByte(hex.Substring(x, 2), 16))
.ToArray();
}
private static string ByteToString(byte[] buff)
{
string sbinary = "";
for (int i = 0; i < buff.Length; i++)
{
sbinary += buff[i].ToString("X2"); // hex format
}
return (sbinary);
}
private static byte[] Combine(params byte[][] arrays)
{
byte[] rv = new byte[arrays.Sum(a => a.Length)];
int offset = 0;
foreach (byte[] array in arrays)
{
System.Buffer.BlockCopy(array, 0, rv, offset, array.Length);
offset += array.Length;
}
return rv;
}
Thanks,

ConcurrentModificationException in iterator.next() I cannot find another solution

I'm currently coding a little net thing and wanted to cicle threw all of my players so I used ArrayLists and Lists but there were alot of Exception so going deep to the problem I replaced them with Iterators but I'm getting Concurrent modification exceptions in all the "it.next()" :/.
So if please you can help me understand the problem :).
#Override
public void run()
{
StringBuilder l = new StringBuilder();
Iterator<UUID> pc;
Iterator<Packet> pa;
while (Jelly.isSTATUS()) {
pc = Jelly.getOnlinePlayers().keySet().iterator();
while (pc.hasNext())
try {
System.out.println("ENTERED!");
Player p = Jelly.getOnlinePlayers().get(pc.next());
System.out.println(p.getIGN());
if (Packetsts.containsKey(p) && !Packetsts.get(p).isEmpty())
try {
pa = Packetsts.get(p).iterator();
while(pa.hasNext()) {
Packet i = pa.next();
for ( String j : i.getData())
l.append(j + ",");
l.append("es");
System.out.println("Data: " + l.toString());
byte[] toSendBytes = l.toString().getBytes();
int toSendLen = toSendBytes.length;
byte[] toSendLenBytes = new byte[4];
toSendLenBytes[0] = (byte)(toSendLen & 0xff);
toSendLenBytes[1] = (byte)(toSendLen >> 8 & 0xff);
toSendLenBytes[2] = (byte)(toSendLen >> 16 & 0xff);
toSendLenBytes[3] = (byte)(toSendLen >> 24 & 0xff);
PrintStreams.get(p).write(toSendLenBytes);
PrintStreams.get(p).write(toSendBytes);
Packetsts.get(p).remove(i);
l.setLength(0);
}
} catch ( Exception ex) { }
} catch (ConcurrentModificationException ex){ ex.printStackTrace(); }
}
System.out.println("END!");
}
Thank you :)
UPDATE:
#Override
public void run()
{
StringBuilder l = new StringBuilder();
Iterator<UUID> pc = Jelly.getOnlinePlayers().keySet().iterator();
Iterator<Packet> pa;
while (Jelly.isSTATUS())
if (!Jelly.getOnlinePlayers().keySet().isEmpty()) {
pc = Jelly.getOnlinePlayers().keySet().iterator();
while (pc.hasNext()) {
UUID u = pc.next();
Player p = Jelly.getOnlinePlayers().get(u);
if (Packetsts.containsKey(p) && !Packetsts.get(p).isEmpty())
try {
pa = Packetsts.get(p).iterator();
while(pa.hasNext()) {
Packet i = pa.next();
for ( String j : i.getData())
l.append(j + ",");
l.append("es");
System.out.println("Data: " + l.toString());
byte[] toSendBytes = l.toString().getBytes();
int toSendLen = toSendBytes.length;
byte[] toSendLenBytes = new byte[4];
toSendLenBytes[0] = (byte)(toSendLen & 0xff);
toSendLenBytes[1] = (byte)(toSendLen >> 8 & 0xff);
toSendLenBytes[2] = (byte)(toSendLen >> 16 & 0xff);
toSendLenBytes[3] = (byte)(toSendLen >> 24 & 0xff);
PrintStreams.get(p).write(toSendLenBytes);
PrintStreams.get(p).write(toSendBytes);
l = new StringBuilder();
}
Packetsts.get(p).clear();
} catch ( Exception ex) { ex.printStackTrace(); }
}
}
System.out.println("END!");
}
Line "UUID u = pc.next();" please, I really hate concurrent modification exception :/
this is not allowed
Packetsts.get(p).remove(i);
as you are simultaneously iterating over the ArrayList which you are trying to modify. How about making a copy of it when the loop begins? What is your end goal after removing the elements?

Android MD5 issue calculating MD5, missing characters

I've been developing an Android App and in certain part of the app I need to calculate the MD5 of a certain string. I've been using the following code, but every now and then the output string if the byte it has to convert to String is lower than 10, then it will miss a 0 in the two byte representation:
MessageDigest di = java.security.MessageDigest.getInstance("MD5");
di.update(cadena.getBytes());
byte mdi[] = di.digest();
StringBuffer md5= new StringBuffer();
for (byte b : mdi) {
md5.append(Integer.toHexString(0xFF & b));
}
For example, if I pass the string 109370 the MD5 it will have to return is 932ff0696b0434d7a83e1ff84fe298c5 but instead it calculates the 932ff0696b434d7a83e1ff84fe298c5.
That's because the byte array has a 4 and Integer.toHexString() is returning only 1 char array instead of two.
Any thought about how can I handle this?
Thanks!
below is the code that i am using:
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class MD5Encode {
private static String convertedToHex(byte[] data) {
StringBuffer buf = new StringBuffer();
for (int i = 0; i < data.length; i++) {
int halfOfByte = (data[i] >>> 4) & 0x0F;
int twoHalfBytes = 0;
do {
if ((0 <= halfOfByte) && (halfOfByte <= 9)) {
buf.append((char) ('0' + halfOfByte));
} else {
buf.append((char) ('a' + (halfOfByte - 10)));
}
halfOfByte = data[i] & 0x0F;
} while (twoHalfBytes++ < 1);
}
return buf.toString();
}
public static String MD5(String text) throws NoSuchAlgorithmException,
UnsupportedEncodingException {
MessageDigest md;
md = MessageDigest.getInstance("MD5");
byte[] md5 = new byte[64];
md.update(text.getBytes("iso-8859-1"), 0, text.length());
md5 = md.digest();
return convertedToHex(md5);
}
}
and use it by this way:
MD5Encode.MD5("your string here")
hope this will help you :)
You can use a java.util.Formatter:
Formatter fmt = new Formatter(md5);
for (byte b : mdi) {
fmt.format("%02x", b&0xff);
}
fmt.close();
Use this:
public String calculateMD5(String string) {
StringBuilder result = new StringBuilder();
try {
MessageDigest m = MessageDigest.getInstance("MD5");
m.update(string.getBytes("UTF8"));
byte s[] = m.digest();
for (int i = 0; i < s.length; i++) {
result.append(Integer.toHexString((0x000000ff & s[i]) | 0xffffff00).substring(6));
}
} catch (NoSuchAlgorithmException e) {
throw new IllegalStateException("Password hash is unsupported by device android implementation.", e);
} catch (UnsupportedEncodingException e) {
throw new IllegalStateException("Password hash is unsupported by device android implementation.", e);
}
return result.toString();
}

Merging two WAVE files on Android (concatenate)

I have been trying to merge two WAVE files on Android for quite some time now but really can't seem to get it working properly.
Everything looks fine, the files are read, and written to the output file which is also readable at a later stage and has the file size I would expect to see.
The problems occur right after the app has finished merging. This message will show in the log: Error occured in updateListener, recording is aborted which is a message from extAudioRecorder and appears when the OnRecordPositionUpdateListener reaches the catch clause (the Exception has the following detailMessage: write failed: EBADF (Bad file number)). This does not seem to break anything so I'm not too worried about this.
The real problem arises when I try to create a MediaPlayer and call the setDataSource(String path) on the MediaPlayer instance. Whenever I do this with a merged file the following error message will show in the log: Unable to to create media player (the IOException that is thrown contains the following detailMessage: setDataSourceFD failed.: status=0x80000000). Note that the first time the file will play perfectly fine (this first file was not made by the combineWaveFiles() method). That Error message appears to indicate that the audio file's format is incorrect and/or can't be read by the MediaPlayer.
My question is if anyone sees any real problems with the code below (I know it's sub-optimal in many ways but I prefer to get it to work first then worry about performance).
public static String MergeRecordings(String cumulativeFile, String recordFile, int sampleRate, int bpp, int bufferSize, int channels) {
if (cumulativeFile == null) {
return recordFile;
} else if (recordFile == null) {
return cumulativeFile;
}
String outputFile = FileUtils.getFilePath(null, MDSettings.shared().getMainActivity());
FileUtils.combineWaveFiles(cumulativeFile, recordFile, outputFile, sampleRate, bpp, bufferSize, channels);
//FileUtils.removeFile(cumulativeFile);
//FileUtils.removeFile(recordFile);
return outputFile;
}
//creates a new file containing file1 + file2 stuck together as such.
private static void combineWaveFiles(String file1, String file2, String outputFile, int sampleRate, int bpp, int bufferSize, int channels) {
FileInputStream in1 = null, in2 = null;
FileOutputStream out = null;
long longSampleRate = sampleRate;
long byteRate = sampleRate * channels * bpp / 8;
byte[] data;
try {
try {
in1 = new FileInputStream(file1);
} catch (Exception e) { }
try {
in2 = new FileInputStream(file2);
} catch (FileNotFoundException e) { }
out = new FileOutputStream(outputFile);
long file1Size = 0;
long file2Size = 0;
if (in1 != null) { file1Size = in1.getChannel().size() - 44; }
if (in2 != null) { file2Size = in2.getChannel().size() - 44; }
long totalAudioLen = file1Size + file2Size;
long totalDataLen = totalAudioLen + 36;
FileUtils.writeWaveFileHeader(out, totalAudioLen, totalDataLen, longSampleRate, channels, byteRate, bpp);
if (in1 != null) {
in1.skip(44);
data = new byte[bufferSize];
if (file1Size < bufferSize) {
data = new byte[(int)file1Size];
}
while (in1.read(data) != -1) {
out.write(data);
file1Size -= bufferSize;
if (file1Size <= 0) {
break;
} else if (file1Size < bufferSize) {
data = new byte[(int)file1Size];
}
}
}
if (in2 != null) {
in2.skip(44);
data = new byte[bufferSize];
if (file2Size < bufferSize) {
data = new byte[(int)file2Size];
}
while (in2.read(data) != -1) {
out.write(data);
file2Size -= bufferSize;
if (file2Size <= 0) {
break;
} else if (file2Size < bufferSize) {
data = new byte[(int)file2Size];
}
}
}
out.close();
if (in1 != null) { in1.close(); }
if (in2 != null) { in2.close(); }
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private static void writeWaveFileHeader(FileOutputStream out, long totalAudioLen, long totalDataLen, long longSampleRate, int channels, long byteRate, int bpp)
throws IOException {
byte[] header = new byte[44];
header[0] = 'R';
header[1] = 'I';
header[2] = 'F';
header[3] = 'F';
header[4] = (byte)(totalDataLen & 0xff);
header[5] = (byte)((totalDataLen >> 8) & 0xff);
header[6] = (byte)((totalDataLen >> 16) & 0xff);
header[7] = (byte)((totalDataLen >> 24) & 0xff);
header[8] = 'W';
header[9] = 'A';
header[10] = 'V';
header[11] = 'E';
header[12] = 'f';
header[13] = 'm';
header[14] = 't';
header[15] = ' ';
header[16] = 16;
header[17] = 0;
header[18] = 0;
header[19] = 0;
header[20] = 1;
header[21] = 0;
header[22] = (byte) channels;
header[23] = 0;
header[24] = (byte)(longSampleRate & 0xff);
header[25] = (byte)((longSampleRate >> 8) & 0xff);
header[26] = (byte)((longSampleRate >> 16) & 0xff);
header[27] = (byte)((longSampleRate >> 24) & 0xff);
header[28] = (byte)(byteRate & 0xff);
header[29] = (byte)((byteRate >> 8) & 0xff);
header[30] = (byte)((byteRate >> 16) & 0xff);
header[31] = (byte)((byteRate >> 24) & 0xff);
header[32] = (byte)(channels * bpp); //(2 * 16 / 8);
header[33] = 0;
header[34] = (byte)bpp;
header[35] = 0;
header[36] = 'd';
header[37] = 'a';
header[38] = 't';
header[39] = 'a';
header[40] = (byte)(totalAudioLen & 0xff);
header[41] = (byte)((totalAudioLen >> 8) & 0xff);
header[42] = (byte)((totalAudioLen >> 16) & 0xff);
header[43] = (byte)((totalAudioLen >> 24) & 0xff);
out.write(header, 0, 44);
}
Large parts of this code are taken from this answer.
i do this exactly in my android app. Instead of two, i merge multiple files based on users selection. I use AsyncTask to merge the samples in the background. Take a look at it here. Just filter the section that you need. If you are curious about my app, its called Sound Recorder + Pro, Beside merge i do mix, add echo and amplify samples:
#Override
protected Void doInBackground(Void... params) {
isProcessingOn=true;
try {
DataOutputStream amplifyOutputStream = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(Environment.getExternalStorageDirectory() + "/Soundrecpluspro/" + year +"-"+ month +"-"+ date +"-"+ hour+"-" + min +"-"+ sec+"ME.wav")));
DataInputStream[] mergeFilesStream = new DataInputStream[selection.size()];
long[] sizes=new long[selection.size()];
for(int i=0; i<selection.size(); i++) {
File file = new File(Environment.getExternalStorageDirectory() + "/Soundrecpluspro/" +selection.get(i));
sizes[i] = (file.length()-44)/2;
}
for(int i =0; i<selection.size(); i++) {
mergeFilesStream[i] =new DataInputStream(new BufferedInputStream(new FileInputStream(Environment.getExternalStorageDirectory() + "/Soundrecpluspro/" +selection.get(i))));
if(i == selection.size()-1) {
mergeFilesStream[i].skip(24);
byte[] sampleRt = new byte[4];
mergeFilesStream[i].read(sampleRt);
ByteBuffer bbInt = ByteBuffer.wrap(sampleRt).order(ByteOrder.LITTLE_ENDIAN);
RECORDER_SAMPLERATE = bbInt.getInt();
mergeFilesStream[i].skip(16);
}
else {
mergeFilesStream[i].skip(44);
}
}
for(int b=0; b<selection.size(); b++) {
for(int i=0; i<(int)sizes[b]; i++) {
byte[] dataBytes = new byte[2];
try {
dataBytes[0] = mergeFilesStream[b].readByte();
dataBytes[1] = mergeFilesStream[b].readByte();
}
catch (EOFException e) {
amplifyOutputStream.close();
}
short dataInShort = ByteBuffer.wrap(dataBytes).order(ByteOrder.LITTLE_ENDIAN).getShort();
float dataInFloat= (float) dataInShort/37268.0f;
short outputSample = (short)(dataInFloat * 37268.0f);
byte[] dataFin = new byte[2];
dataFin[0] = (byte) (outputSample & 0xff);
dataFin[1] = (byte)((outputSample >> 8) & 0xff);
amplifyOutputStream.write(dataFin, 0 , 2);
}
}
amplifyOutputStream.close();
for(int i=0; i<selection.size(); i++) {
mergeFilesStream[i].close();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
long size =0;
try {
FileInputStream fileSize = new FileInputStream(Environment.getExternalStorageDirectory() + "/Soundrecpluspro/"+year +"-"+ month +"-"+ date +"-"+ hour+"-" + min +"-"+ sec+"ME.wav");
size = fileSize.getChannel().size();
fileSize.close();
} catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
final int RECORDER_BPP = 16;
long datasize=size+36;
long byteRate = (RECORDER_BPP * RECORDER_SAMPLERATE)/8;
long longSampleRate = RECORDER_SAMPLERATE;
byte[] header = new byte[44];
header[0] = 'R'; // RIFF/WAVE header
header[1] = 'I';
header[2] = 'F';
header[3] = 'F';
header[4] = (byte) (datasize & 0xff);
header[5] = (byte) ((datasize >> 8) & 0xff);
header[6] = (byte) ((datasize >> 16) & 0xff);
header[7] = (byte) ((datasize >> 24) & 0xff);
header[8] = 'W';
header[9] = 'A';
header[10] = 'V';
header[11] = 'E';
header[12] = 'f'; // 'fmt ' chunk
header[13] = 'm';
header[14] = 't';
header[15] = ' ';
header[16] = 16; // 4 bytes: size of 'fmt ' chunk
header[17] = 0;
header[18] = 0;
header[19] = 0;
header[20] = 1; // format = 1
header[21] = 0;
header[22] = (byte) 1;
header[23] = 0;
header[24] = (byte) (longSampleRate & 0xff);
header[25] = (byte) ((longSampleRate >> 8) & 0xff);
header[26] = (byte) ((longSampleRate >> 16) & 0xff);
header[27] = (byte) ((longSampleRate >> 24) & 0xff);
header[28] = (byte) (byteRate & 0xff);
header[29] = (byte) ((byteRate >> 8) & 0xff);
header[30] = (byte) ((byteRate >> 16) & 0xff);
header[31] = (byte) ((byteRate >> 24) & 0xff);
header[32] = (byte) ((RECORDER_BPP) / 8); // block align
header[33] = 0;
header[34] = RECORDER_BPP; // bits per sample
header[35] = 0;
header[36] = 'd';
header[37] = 'a';
header[38] = 't';
header[39] = 'a';
header[40] = (byte) (size & 0xff);
header[41] = (byte) ((size >> 8) & 0xff);
header[42] = (byte) ((size >> 16) & 0xff);
header[43] = (byte) ((size >> 24) & 0xff);
// out.write(header, 0, 44);
try {
RandomAccessFile rFile = new RandomAccessFile(Environment.getExternalStorageDirectory() + "/Soundrecpluspro/" +year +"-"+ month +"-"+ date +"-"+ hour+"-" + min +"-"+ sec+ "ME.wav", "rw");
rFile.seek(0);
rFile.write(header);
rFile.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
Try with this code for concatenating the wav files:
public class ConcateSongActivity extends Activity {
Button mbutt;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mbutt = (Button)findViewById(R.id.button_clickme);
mbutt.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
try {
FileInputStream fis1 = new FileInputStream("/sdcard/MJdangerous.wav");
FileInputStream fis2 = new FileInputStream("/sdcard/MJBad.wav");
SequenceInputStream sis = new SequenceInputStream(fis1,fis2);
FileOutputStream fos = new FileOutputStream(new File("/sdcard/MJdangerousMJBad.wav"));
int temp;
try {
while ((temp = sis.read())!= -1){
fos.write(temp);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
} }
Note: don't forget to give this permission WRITE_EXTERNAL_STORAGE
other tricks:
This is the methods used to mix 3 sounds together:
private void mixFiles(){
try {
InputStream is1 = getResources().openRawResource(R.raw.test1);
List<Short> music1 = createMusicArray(is1);
InputStream is2 = getResources().openRawResource(R.raw.test2);
List<Short> music2 = createMusicArray(is2);
completeStreams(music1,music2);
short[] music1Array = buildShortArray(music1);
short[] music2Array = buildShortArray(music2);
short[] output = new short[music1Array.length];
for(int i=0; i < output.length; i++){
float samplef1 = music1Array[i] / 32768.0f;
float samplef2 = music2Array[i] / 32768.0f;
float mixed = samplef1 + samplef2;
// reduce the volume a bit:
mixed *= 0.8;
// hard clipping
if (mixed > 1.0f) mixed = 1.0f;
if (mixed < -1.0f) mixed = -1.0f;
short outputSample = (short)(mixed * 32768.0f);
output[i] = outputSample;
}
saveToFile(output);
} catch (NotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Once we have a PCM mixed sound, it can be transformed in a .wav file so that every player can read it.
/**
* Dealing with big endian streams
* #param byte0
* #param byte1
* #return a shrt with the two bytes swapped
*/
private static short swapBytes(byte byte0, byte byte1){
return (short)((byte1 & 0xff) << 8 | (byte0 & 0xff));
}
/**
* From file to byte[] array
* #param sample
* #param swap should swap bytes?
* #return
* #throws IOException
*/
public static byte[] sampleToByteArray(File sample, boolean swap) throws IOException{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(sample));
int BUFFERSIZE = 4096;
byte[] buffer = new byte[BUFFERSIZE];
while(bis.read(buffer) != - 1){
baos.write(buffer);
}
byte[] outputByteArray = baos.toByteArray();
bis.close();
baos.close();
if(swap){
for(int i=0; i < outputByteArray.length - 1; i=i+2){
byte byte0 = outputByteArray[i];
outputByteArray[i] = outputByteArray[i+1];
outputByteArray[i+1] = byte0;
}
}
return outputByteArray;
}
/**
* Read a file and returns its contents as array of shorts
* #param sample the sample file
* #param swap true if we should swap the bytes of short (reading a little-endian file), false otherwise (reading a big-endian file)
* #return
* #throws IOException
*/
public static short[] sampleToShortArray(File sample, boolean swap) throws IOException{
short[] outputArray = new short[(int)sample.length()/2];
byte[] outputByteArray = sampleToByteArray(sample,false);
for(int i=0, j=0; i < outputByteArray.length; i+= 2, j++){
if(swap){
outputArray[j] = swapBytes(outputByteArray[i], outputByteArray[i + 1]);
}
else{
outputArray[j] = swapBytes(outputByteArray[i + 1], outputByteArray[i]);
}
}
return outputArray;
}
public void completeStreams(List<Short> mListShort_1, List<Short> mListShort_2) {
//TODO: check length
int size_a = mListShort_1.size();
int size_b = mListShort_2.size();
if (size_a > size_b){
// adding series of '0'
for (int i = size_b+1; i <= size_a; i++) {
mListShort_2.set(i, (short) 0);
}
} else if (size_a < size_b) {
for (int i = size_a+1; i <= size_b; i++) {
mListShort_1.set(i, (short) 0);
}
} else {
//do nothing
}
}
Credits: nalitzis

Categories