001/** 002 * 003 * Copyright (c) 2014, the Railo Company Ltd. All rights reserved. 004 * 005 * This library is free software; you can redistribute it and/or 006 * modify it under the terms of the GNU Lesser General Public 007 * License as published by the Free Software Foundation; either 008 * version 2.1 of the License, or (at your option) any later version. 009 * 010 * This library is distributed in the hope that it will be useful, 011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 013 * Lesser General Public License for more details. 014 * 015 * You should have received a copy of the GNU Lesser General Public 016 * License along with this library. If not, see <http://www.gnu.org/licenses/>. 017 * 018 **/ 019package lucee.runtime.cache.eh; 020 021import java.io.ByteArrayInputStream; 022import java.io.IOException; 023import java.io.InputStream; 024 025import lucee.commons.io.CharsetUtil; 026 027 028/** 029 * 030 */ 031public final class MD5 032{ 033 /** 034 * return md5 from string as string 035 * @param str plain string to get md5 from 036 * @return md5 from string 037 * @throws IOException 038 */ 039 public static String getDigestAsString(String str) throws IOException { 040 return new MD5(str).getDigest(); 041 } 042 043 044 045 private static String stringify(byte digest[]) { 046 char[] chars = new char[2*digest.length]; 047 int h; 048 int l; 049 int count=0; 050 for (int i = 0 ; i < digest.length; i++) { 051 h = (digest[i] & 0xf0) >> 4 ; 052 l = (digest[i] & 0x0f) ; 053 chars[count++]= ((char)((h>9) ? 'a'+h-10 : '0'+h)); 054 chars[count++]= ((char)((l>9) ? 'a'+l-10 : '0'+l)); 055 } 056 return new String(chars) ; 057 } 058 059 private final int F(int x, int y, int z) 060 { 061 return x & y | ~x & z; 062 } 063 064 private final int G(int x, int y, int z) 065 { 066 return x & z | y & ~z; 067 } 068 069 private final int H(int x, int y, int z) 070 { 071 return x ^ y ^ z; 072 } 073 074 private final int I(int x, int y, int z) 075 { 076 return y ^ (x | ~z); 077 } 078 079 private final int rotate_left(int x, int n) 080 { 081 return x << n | x >>> 32 - n; 082 } 083 084 private final int FF(int a, int b, int c, int d, int x, int s, int ac) 085 { 086 a += F(b, c, d) + x + ac; 087 a = rotate_left(a, s); 088 a += b; 089 return a; 090 } 091 092 private final int GG(int a, int b, int c, int d, int x, int s, int ac) 093 { 094 a += G(b, c, d) + x + ac; 095 a = rotate_left(a, s); 096 a += b; 097 return a; 098 } 099 100 private final int HH(int a, int b, int c, int d, int x, int s, int ac) 101 { 102 a += H(b, c, d) + x + ac; 103 a = rotate_left(a, s); 104 a += b; 105 return a; 106 } 107 108 private final int II(int a, int b, int c, int d, int x, int s, int ac) 109 { 110 a += I(b, c, d) + x + ac; 111 a = rotate_left(a, s); 112 a += b; 113 return a; 114 } 115 116 private final void decode(int output[], byte input[], int off, int len) 117 { 118 int i = 0; 119 for(int j = 0; j < len; j += 4) 120 { 121 output[i] = input[off + j] & 0xff | (input[off + j + 1] & 0xff) << 8 | (input[off + j + 2] & 0xff) << 16 | (input[off + j + 3] & 0xff) << 24; 122 i++; 123 } 124 125 } 126 127 private final void transform(byte block[], int offset) 128 { 129 int a = state[0]; 130 int b = state[1]; 131 int c = state[2]; 132 int d = state[3]; 133 int x[] = new int[16]; 134 135 136 decode(x, block, offset, 64); 137 a = FF(a, b, c, d, x[0], 7, 0xd76aa478); 138 d = FF(d, a, b, c, x[1], 12, 0xe8c7b756); 139 c = FF(c, d, a, b, x[2], 17, 0x242070db); 140 b = FF(b, c, d, a, x[3], 22, 0xc1bdceee); 141 a = FF(a, b, c, d, x[4], 7, 0xf57c0faf); 142 d = FF(d, a, b, c, x[5], 12, 0x4787c62a); 143 c = FF(c, d, a, b, x[6], 17, 0xa8304613); 144 b = FF(b, c, d, a, x[7], 22, 0xfd469501); 145 a = FF(a, b, c, d, x[8], 7, 0x698098d8); 146 d = FF(d, a, b, c, x[9], 12, 0x8b44f7af); 147 c = FF(c, d, a, b, x[10], 17, -42063); 148 b = FF(b, c, d, a, x[11], 22, 0x895cd7be); 149 a = FF(a, b, c, d, x[12], 7, 0x6b901122); 150 d = FF(d, a, b, c, x[13], 12, 0xfd987193); 151 c = FF(c, d, a, b, x[14], 17, 0xa679438e); 152 b = FF(b, c, d, a, x[15], 22, 0x49b40821); 153 a = GG(a, b, c, d, x[1], 5, 0xf61e2562); 154 d = GG(d, a, b, c, x[6], 9, 0xc040b340); 155 c = GG(c, d, a, b, x[11], 14, 0x265e5a51); 156 b = GG(b, c, d, a, x[0], 20, 0xe9b6c7aa); 157 a = GG(a, b, c, d, x[5], 5, 0xd62f105d); 158 d = GG(d, a, b, c, x[10], 9, 0x2441453); 159 c = GG(c, d, a, b, x[15], 14, 0xd8a1e681); 160 b = GG(b, c, d, a, x[4], 20, 0xe7d3fbc8); 161 a = GG(a, b, c, d, x[9], 5, 0x21e1cde6); 162 d = GG(d, a, b, c, x[14], 9, 0xc33707d6); 163 c = GG(c, d, a, b, x[3], 14, 0xf4d50d87); 164 b = GG(b, c, d, a, x[8], 20, 0x455a14ed); 165 a = GG(a, b, c, d, x[13], 5, 0xa9e3e905); 166 d = GG(d, a, b, c, x[2], 9, 0xfcefa3f8); 167 c = GG(c, d, a, b, x[7], 14, 0x676f02d9); 168 b = GG(b, c, d, a, x[12], 20, 0x8d2a4c8a); 169 a = HH(a, b, c, d, x[5], 4, 0xfffa3942); 170 d = HH(d, a, b, c, x[8], 11, 0x8771f681); 171 c = HH(c, d, a, b, x[11], 16, 0x6d9d6122); 172 b = HH(b, c, d, a, x[14], 23, 0xfde5380c); 173 a = HH(a, b, c, d, x[1], 4, 0xa4beea44); 174 d = HH(d, a, b, c, x[4], 11, 0x4bdecfa9); 175 c = HH(c, d, a, b, x[7], 16, 0xf6bb4b60); 176 b = HH(b, c, d, a, x[10], 23, 0xbebfbc70); 177 a = HH(a, b, c, d, x[13], 4, 0x289b7ec6); 178 d = HH(d, a, b, c, x[0], 11, 0xeaa127fa); 179 c = HH(c, d, a, b, x[3], 16, 0xd4ef3085); 180 b = HH(b, c, d, a, x[6], 23, 0x4881d05); 181 a = HH(a, b, c, d, x[9], 4, 0xd9d4d039); 182 d = HH(d, a, b, c, x[12], 11, 0xe6db99e5); 183 c = HH(c, d, a, b, x[15], 16, 0x1fa27cf8); 184 b = HH(b, c, d, a, x[2], 23, 0xc4ac5665); 185 a = II(a, b, c, d, x[0], 6, 0xf4292244); 186 d = II(d, a, b, c, x[7], 10, 0x432aff97); 187 c = II(c, d, a, b, x[14], 15, 0xab9423a7); 188 b = II(b, c, d, a, x[5], 21, 0xfc93a039); 189 a = II(a, b, c, d, x[12], 6, 0x655b59c3); 190 d = II(d, a, b, c, x[3], 10, 0x8f0ccc92); 191 c = II(c, d, a, b, x[10], 15, 0xffeff47d); 192 b = II(b, c, d, a, x[1], 21, 0x85845dd1); 193 a = II(a, b, c, d, x[8], 6, 0x6fa87e4f); 194 d = II(d, a, b, c, x[15], 10, 0xfe2ce6e0); 195 c = II(c, d, a, b, x[6], 15, 0xa3014314); 196 b = II(b, c, d, a, x[13], 21, 0x4e0811a1); 197 a = II(a, b, c, d, x[4], 6, 0xf7537e82); 198 d = II(d, a, b, c, x[11], 10, 0xbd3af235); 199 c = II(c, d, a, b, x[2], 15, 0x2ad7d2bb); 200 b = II(b, c, d, a, x[9], 21, 0xeb86d391); 201 state[0] += a; 202 state[1] += b; 203 state[2] += c; 204 state[3] += d; 205 } 206 207 private final void update(byte input[], int len) 208 { 209 int index = (int)(count >> 3) & 0x3f; 210 count += len << 3; 211 int partLen = 64 - index; 212 int i = 0; 213 if(len >= partLen) 214 { 215 System.arraycopy(input, 0, buffer, index, partLen); 216 transform(buffer, 0); 217 for(i = partLen; i + 63 < len; i += 64) 218 transform(input, i); 219 220 index = 0; 221 } else 222 { 223 i = 0; 224 } 225 System.arraycopy(input, i, buffer, index, len - i); 226 } 227 228 private byte[] end() 229 { 230 byte bits[] = new byte[8]; 231 for(int i = 0; i < 8; i++) 232 bits[i] = (byte)(int)(count >>> i * 8 & 255L); 233 234 int index = (int)(count >> 3) & 0x3f; 235 int padlen = index >= 56 ? 120 - index : 56 - index; 236 update(padding, padlen); 237 update(bits, 8); 238 return encode(state, 16); 239 } 240 241 private byte[] encode(int input[], int len) 242 { 243 byte output[] = new byte[len]; 244 int i = 0; 245 for(int j = 0; j < len; j += 4) 246 { 247 output[j] = (byte)(input[i] & 0xff); 248 output[j + 1] = (byte)(input[i] >> 8 & 0xff); 249 output[j + 2] = (byte)(input[i] >> 16 & 0xff); 250 output[j + 3] = (byte)(input[i] >> 24 & 0xff); 251 i++; 252 } 253 254 return output; 255 } 256 257 /** 258 * @return return the digest 259 * @throws IOException 260 */ 261public String getDigest() throws IOException { 262 byte buffer[] = new byte[1024]; 263 int got = -1; 264 if(digest != null) 265 return stringify(digest); 266 while((got = in.read(buffer)) > 0) 267 update(buffer, got); 268 digest = end(); 269 return stringify(digest); 270 271 } 272 273 274 275 /** 276 * @param input 277 */ 278public MD5(String input) { 279 in = null; 280 //stringp = false; 281 state = null; 282 count = 0L; 283 buffer = null; 284 digest = null; 285 byte bytes[] = input.getBytes(CharsetUtil.UTF8); 286 in = new ByteArrayInputStream(bytes); 287 state = new int[4]; 288 buffer = new byte[64]; 289 count = 0L; 290 state[0] = 0x67452301; 291 state[1] = 0xefcdab89; 292 state[2] = 0x98badcfe; 293 state[3] = 0x10325476; 294 } 295/* 296 public static final int DIGEST_CHARS = 32; 297 public static final int DIGEST_BYTES = 16; 298 private static final int BUFFER_SIZE = 1024; 299 private static final int S11 = 7; 300 private static final int S12 = 12; 301 private static final int S13 = 17; 302 private static final int S14 = 22; 303 private static final int S21 = 5; 304 private static final int S22 = 9; 305 private static final int S23 = 14; 306 private static final int S24 = 20; 307 private static final int S31 = 4; 308 private static final int S32 = 11; 309 private static final int S33 = 16; 310 private static final int S34 = 23; 311 private static final int S41 = 6; 312 private static final int S42 = 10; 313 private static final int S43 = 15; 314 private static final int S44 = 21;*/ 315 private static byte padding[] = { 316 -128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 317 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 318 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 319 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 320 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 321 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 322 0, 0, 0, 0 323 }; 324 private InputStream in; 325 //private boolean stringp; 326 private int state[]; 327 private long count; 328 private byte buffer[]; 329 private byte digest[]; 330 331}