JavaScript 224 LOC
This function will calculate all results of a given length, optionally limited to results starting with a given string, that is if it's done within the 1 second that I have allotted. If no results exist it is done virtually instantly. The function rely heavily on a very slow custom built 64 bit integer library, an equivalent C function would probably be 100 to 1000 times faster. I might set up a nice web interface.
<html>
<head>
<title>Break Hash</title>
</head>
<body>
<pre id="out"></pre>
<script>
function to64(inp){
var res=[]
res[0]=inp%(256*256*256)
inp=Math.floor(inp/(256*256*256))
res[1]=inp%(256*256*256)
inp=Math.floor(inp/(256*256*256))
res[2]=inp%(256*256)
return res
}
function add64(inp1,inp2){
var res=[]
res[0]=inp1[0]+inp2[0]
res[1]=inp1[1]+inp2[1]+Math.floor(res[0]/(256*256*256))
res[2]=(inp1[2]+inp2[2]+Math.floor(res[1]/(256*256*256)))&(256*256-1)
res[0]&=(256*256*256-1)
res[1]&=(256*256*256-1)
return res
}
function neg64(inp){
var res=[]
res[0]=inp[0]^(256*256*256-1)
res[1]=inp[1]^(256*256*256-1)
res[2]=inp[2]^(256*256-1)
return add64(res,[1,0,0])
}
function abs64(inp){
if(inp[2]>=(256*128)){
return neg64(inp)
}
return inp
}
function mul64(inp1,inp2){
var res=[]
res[0]=inp1[0]*inp2[0]
res[1]=inp1[1]*inp2[0]+inp1[0]*inp2[1]+Math.floor(res[0]/(256*256*256))
res[2]=inp1[2]*inp2[0]+inp1[1]*inp2[1]+inp1[0]*inp2[2]+Math.floor(res[1]/(256*256*256))
overflow=(res[2]>=(256*256)) //Global shortcut
res[2]&=(256*256-1)
res[0]&=(256*256*256-1)
res[1]&=(256*256*256-1)
return res
}
function mod64(inp1,inp2){ //64,float -> float
var res=inp1[2]%inp2
res=(res*(256*256*256)+inp1[1])%inp2
return (res*(256*256*256)+inp1[0])%inp2
}
function div64(inp1,inp2){ //64,float -> 64
var res=[]
res[2]=Math.floor(inp1[2]/inp2)
var mem1=inp1[1]+(inp1[2]%inp2)*(256*256*256)
res[1]=Math.floor(mem1/inp2)
res[0]=Math.floor((inp1[0]+(mem1%inp2)*(256*256*256))/inp2)
return add64(res,[0,0,0])
}
function cmp64(inp1,inp2){
for(var a=2;a>=0;a--){
if(inp1[a]>inp2[a]){
return 1
}
if(inp1[a]<inp2[a]){
return -1
}
}
return 0
}
function string64(inp){
var res=""
while(cmp64(inp,[0,0,0])){
res=mod64(inp,10)+res
inp=div64(inp,10)
}
return res||"0"
}
function hashPassword(password){
var i
password=stringtoarray(password)
var hash = to64(0);
var multiplier = to64(13);
for (i = 0; i < password.length; i++){
multiplier = add64(multiplier,[1,0,0])
hash = add64(mul64(hash,multiplier),to64(password[i]));
}
hash = abs64(hash);
hash = mul64(hash,to64(Math.pow(2,mod64(hash,11))));
hash = abs64(hash);
return string64(hash)
}
function stringtoarray(password){
var i
if((typeof password)=="string"){
var password2 = password.toUpperCase();
password=[]
for(i=0;i<password2.length;i++){
password[i]=password2.charCodeAt(i)
}
}
return password
}
function reverse(hash,start,len){
var maxtime=(+new Date())+1000
var m1=neg64(to64(1))
start=stringtoarray(start)
var multipliers=[]
var multipliersum=[]
var max=[]
var min=[]
var firstlimit=0
multipliers[len-1]=[1,0,0]
multipliersum[len-1]=[1,0,0]
max[len-1]=[126,0,0]
min[len-1]=[32,0,0]
for(var a=len-2;a>=0;a--){
multipliers[a]=mul64(multipliers[a+1],to64(15+a))
multipliersum[a]=add64(multipliers[a],multipliersum[a+1])
min[a]=mul64(multipliersum[a],[32,0,0])
max[a]=mul64(multipliersum[a],[126,0,0])
if(overflow && !firstlimit){
firstlimit=a+1
}
}
var startvalue=[0,0,0]
for(var a=0;a<start.length;a++){
startvalue=add64(startvalue,mul64(to64(start[a]),multipliers[a]))
}
startvalue=neg64(startvalue)
allowed=[]
for(a=0;a<32;a++){
allowed[a]=false
}
for(a=32;a<97;a++){
allowed[a]=true
}
for(a=97;a<123;a++){
allowed[a]=false
}
for(a=123;a<127;a++){
allowed[a]=true
}
for(a=127;a<256;a++){
allowed[a]=false
}
var results=[]
function arrtostring(arr){
str=""
for(var a=0;a<arr.length;a++){
//str+=String.fromCharCode(arr[a])
str+="&#"+arr[a]+";"
}
return str
}
function makepwd(ihash){ //This is where clock cycles go to die
ihash=add64(ihash,startvalue)
stringarr=[]
for(var a=0;a<start.length;a++){
stringarr[a]=start[a]
}
function addrest(ihash,startfrom){
if(maxtime<(+new Date())){
return
}
var a
var jhash
if(startfrom==len){
if(cmp64(ihash,[0,0,0])==0){
results[results.length]=arrtostring(stringarr)
}
}
else if(startfrom<firstlimit || ((cmp64(ihash,min[startfrom])!=-1) && (cmp64(ihash,max[startfrom])!=1))){
for(a=32;a<127;a++){
if(allowed[a]){
jhash=add64(ihash,neg64(mul64(to64(a),multipliers[startfrom])))
stringarr[startfrom]=a
addrest(jhash,startfrom+1)
}
}
}
}
addrest(ihash,start.length)
}
function reversemod(ihash){
if(ihash[2]<(128*256)){
if(mod64(ihash,11)==0){
makepwd(ihash)
makepwd(neg64(ihash))
}
}
var modresult=1
var a
var addlim
var jhash
while(mod64(ihash,2)==0){
ihash=div64(ihash,2)
addlim=Math.pow(2,modresult-1)
for(a=0;a<addlim;a++){
jhash=add64(to64(a*Math.pow(2,64-modresult)),ihash)
if(mod64(jhash,11)==modresult){
makepwd(jhash)
makepwd(neg64(jhash))
}
}
modresult++
}
}
reversemod(hash)
reversemod(neg64(hash))
return results
}
document.getElementById("out").innerHTML=reverse(to64(224443104),"ebusiness",22).join("<br>")
//document.getElementById("out").innerHTML=hashPassword("EBUSINESS\"XUWL]NHHHF{I")
</script>
</body>
</html>
Some collisions for 224443104
EBUSINESS"XUWL]NHHHF{I
EBUSINESS"XUWL]NHHHF|&
EBUSINESS"XUWL]NHHHGYI
EBUSINESS"XUWL]NHHHGZ&
EBUSINESS"XUWL]NHHHH7I
(short) password.chartAt(i)do? Will it return the ASCII code of the character?A -> 65etc? – Dogbert Mar 7 '11 at 10:00