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 **/ 019/** 020 * Implements the CFML Function hash 021 */ 022package lucee.runtime.functions.string; 023 024import java.security.MessageDigest; 025 026import lucee.commons.digest.HashUtil; 027import lucee.commons.lang.StringUtil; 028import lucee.commons.lang.SystemOut; 029import lucee.runtime.PageContext; 030import lucee.runtime.config.Config; 031import lucee.runtime.exp.PageException; 032import lucee.runtime.ext.function.Function; 033import lucee.runtime.op.Caster; 034 035public final class Hash implements Function { 036 037 private static final long serialVersionUID = 1161445102079248547L; 038 039 // function for old code in ra files calling this function 040 public static String call(PageContext pc, String input) throws PageException { 041 return invoke( pc.getConfig(), input, null, null, 1 ); 042 } 043 public static String call(PageContext pc , String input, String algorithm) throws PageException { 044 return invoke( pc.getConfig(), input, algorithm, null, 1 ); 045 } 046 public static String call(PageContext pc , String input, String algorithm, String encoding) throws PageException { 047 return invoke( pc.getConfig(), input, algorithm, encoding, 1 ); 048 } 049 ////// 050 051 052 public static String call(PageContext pc, Object input) throws PageException { 053 return invoke( pc.getConfig(), input, null, null, 1 ); 054 } 055 056 public static String call(PageContext pc , Object input, String algorithm) throws PageException { 057 return invoke( pc.getConfig(), input, algorithm, null, 1 ); 058 } 059 060 public static String call(PageContext pc , Object input, String algorithm, String encoding) throws PageException { 061 return invoke( pc.getConfig(), input, algorithm, encoding, 1 ); 062 } 063 064 public static String call(PageContext pc , Object input, String algorithm, String encoding, double numIterations) throws PageException { 065 int ni=(int)numIterations; 066 if(ni<1)ni=1; 067 return invoke( pc.getConfig(), input, algorithm, encoding, ni); 068 } 069 070 /*/ this method signature was called from ConfigWebAdmin.createUUID(), comment this comment to enable 071 public synchronized static String invoke(Config config, Object input, String algorithm, String encoding) throws PageException { 072 073 return invoke(config, input, algorithm, encoding, 1); 074 } //*/ 075 076 public static String invoke(Config config, Object input, String algorithm, String encoding, int numIterations) throws PageException { 077 078 if(StringUtil.isEmpty(algorithm))algorithm="md5"; 079 else algorithm=algorithm.trim().toLowerCase(); 080 if("cfmx_compat".equals(algorithm)) algorithm="md5"; 081 else if("quick".equals(algorithm)) { 082 if(numIterations>1) 083 SystemOut.printDate("for algorithm [quick], argument numIterations makes no sense, because this algorithm has no security in mind"); 084 return HashUtil.create64BitHashAsString(Caster.toString(input), 16); 085 } 086 087 088 089 if(StringUtil.isEmpty(encoding))encoding=config.getWebCharset(); 090 byte[] data = null; 091 092 try { 093 if(input instanceof byte[]) data = (byte[])input; 094 else data = Caster.toString(input).getBytes( encoding ); 095 MessageDigest md=MessageDigest.getInstance(algorithm); 096 md.reset(); 097 for(int i=0; i<numIterations; i++) { 098 data=md.digest(data); 099 } 100 return lucee.commons.digest.Hash.toHexString(data,true); 101 } 102 catch (Throwable t) { 103 throw Caster.toPageException(t); 104 } 105 } 106 107}