HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Hash functions.

04-17-2004, 09:55 PM#1
The Gearhead
Need assistance, as soon as can be provided.

I need to know how to convert a player's name into a hash... a level number, etc.

I am generating a point system for my TD, similar to the Dark Deeds system.

However I dont want mine to be (easily) cracked.

I know how to manipulate numbers, thats not the difficult part. I need to know how to use JASS in order to generate hash codes (preferably hex, even better if its ASCII)

Edit: Specifically, turning ascii names into numbers... or ascii text.


Here's what I thought of so far...

Making a hash of the players name, and using that as the 'base' of the code to enter points.

Then, create a header which would give semi-coded #ofroundswon, #ofleaks, etc... but in such a way that the number of levels completed in succession can be shown.

It'd be a difficult task, yes. That's why I'm asking for help from those coders out there.

The code will likely have to be 32 characters, as well.

I'm trying to think how to make it work with higher levels being worth more points.
04-17-2004, 10:29 PM#2
Vidstige
Could you try to specify the part you need help with in a more structured way? Like with a matemathical example, pseudo-code or a function header? Maybe you should try to list exactly what information you want to be coded into your magic save number.

It shouldn't be to difficult to code the information into the save number, depending on the choosen length of the save number and on how hard it should be to crack it.
04-17-2004, 10:45 PM#3
The Gearhead
Well...

The first part of the string would be the points, that needs to be a simple number, converted to Hex for space.

Then, in generating the following would need to be combined in a way that can be undone.

The name, encoded. The points, encoded. The number of leaks, number of rounds played.

I know that a hash is a one way equation. Such as converting a real number to an integer. Int(Pi) returns 3 and there is no way to find pi using 3. So what I need to figure out is how to turn stuff into a hash, using JASS. Consider me a javascript simpleton, if you will, as long as it helps you teach me. Obviously the information not provided by the player, the number of leaks and number of rounds accumulated, cannot be hashed. The stuff which can is the player name and points.

Hell, maybe I'm wrong. But, I need help making this possible.
04-18-2004, 12:13 AM#4
The Gearhead
Long codes are also harder to crack.


That, and its not like people will be able to use base 90 to input the code.
04-18-2004, 12:28 AM#5
The Gearhead
Ahuh, so I'd have to take it to base 90, and then convert each character in the string to an ascii character. Then, when I input it, it deconverts.

Yeah, that makes sense.

But still, the actual hashing function is the most difficult part, as I do not know how to do it.

*goes back to looking*
04-18-2004, 12:29 AM#6
Cubasis
Ahhh, passwords, what a subject :)

Anyways, firstly, I don't really reccomend you to exceed base-64, as already then are you using symbols that can be confused together, (I and J and 1 are all very similar in WC3). Also, 64 is a good numbers, as those are 6 bits. A secondary is taking it down to base-32, where there are only capped characters, numbers, and bla.

Anyhow, you don't really have to re-invent the wheel, as Peppar has made a incredible password API that is little-known, and even if everybody knew about it, there is VERY little people can do to hack it.

Basicly, it uses a fair enough algorithm to create a unique integer for a player name. Then it...uses this integer as the seed for a random number generator :), where the password is all decoded with random numbers.

Here is it: http://kattana.users.whitehat.dk/viewfunc.php?id=288

You need to know some jass to use it properly. Scroll all the way down to see a example of it's use.

Cubasis
04-18-2004, 12:55 AM#7
The Gearhead
Well, I'd really prefer if I could write my own system.

But, to do this I need help. So please, tell me where I need to look and where I need to start to learn this. Yes, I can understand a bit of that API but most of it is simply... beyond me. I do not understand jass!



An example of 'complete senselessness'

Code:
function CustomRNG takes integer last returns integer
    // the 0 can be changed to almost anything
    // the 16807 can be changed to any simialler sized prime, altough not all work well
    return ModuloInteger(last *  16807 +  0,   2147483647) 
endfunction

Okay. So, it uses the variable last, and multiplies it by a prime which is right around 2^14, and then makes it less than 32 bits via the Modular.

Where does it get last?

Nowhere else in the API is last used. Nowhere. But ModuloInteger is used multiple times!

How does it define ModuloInteger when there is no last?!
04-18-2004, 01:49 AM#8
The Gearhead
I understand, however, assistance would be greatly appreciated.
04-18-2004, 04:00 AM#9
The Gearhead
Is it possible to do this in GUI? Hmm...
04-18-2004, 04:18 AM#10
The Gearhead
Heh. Okay, well, I'll probably end up using a rare or unique algorithm, and shortening the string length that it displays.

Some questions:

When specifying variables, there are some odd procedures going on in Java which I dont get.

Code:
var hexcase = 0;  /* hex output format. 0 - lowercase; 1 - uppercase        */
// many lines lower
  var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";

I assume that what is going on is that the ? represents a boolean condition, where 1 is true and 0 is false. Which goes with the comment.

Another thing I've seen is for loops... do they always use i? I assume i thus stands for integer. Then, what is i++?

Code:
for(var i = 0; i < 16; i++) 

So, for the variable i, it will go from 0 to 16... or less than 16?

And what is i++?

Does it have to be i, or can it be say, g?


If you could, please get on MSN.

If not, contact me via

Aim: Anpheus
MSN: Aaron @ frieltek . com (sans spaces)
04-18-2004, 04:50 AM#11
Cubasis
Ok, well, all that stuff is a API for you to use, the usage of that API is shown at the bottom, but that example is saving a hero, so that is much more advanced, here is a example if you wanna store 3 values that can be of a size 0-1023:

Code:
function Save takes nothing returns string
local integer temp
 
call ClearBits(42)
 
call Integer2Bits(udg_TempValue1,0,10)
call Integer2Bits(udg_TempValue2,10,20)
call Integer2Bits(udg_TempValue3,20,30)
 
//Checksum
set temp = GenerateCRC(256,30)
call Integer2Bits(temp, 30, 38)
set temp = Name2IntHashFunction(GetPlayerName(udg_TempPlayer), 37111)
call ScrambleSwitch(temp, 38)
call ScrambleXOR(temp*2, 38)
set ran = GetRandomInt(0,15)
call Integer2Bits(temp,38,42)
call ScrambleXOR(temp,38)
set udg_TempPassword = CompilePassword(42)
endfunction
 
function Load takes nothing returns nothing
local integer temp
local string s
 
call ClearBits(42)
 
set s = DecompilePassword(udg_TempPassword,42)
if (s != "") then
call DisplayTextToPlayer(udg_TempPlayer, 0.0,0.0, "Invalid Password")
set udg_TempResult = 2
return
endif
 
set temp = Bits2Integer(38,42)
call ScrambleXOR(temp,38)
 
set temp = Name2IntHashFunction(GetPlayerName(udg_TempPlayer), 37111)
call ScrambleXOR(temp*2, 38)
call ScrambleSwitch(temp, 38)
 
set temp = GenerateCRC(256,30)
if (Bits2Integer(30,38) != temp) then
call DisplayTextToPlayer(udg_TempPlayer, 0.0,0.0, "Invalid Password - Checksum failed")
set udg_TempResult = 1
return
endif
 
set udg_TempValue1 = Bits2Integer(0,10)
set udg_TempValue2 = Bits2Integer(10,20)
set udg_TempValue3 = Bits2Integer(20,30)
 
set udg_TempResult = 0
endfunction

Here, so, that code will use Graters' module to generate a complete password for you. And it's not more than 7 characters... do you get any better than that? The reason that is, is that this module is 100% bit-oriented...so you can make passwords REALLY small. This password also has all kinds of typical protection, including checksum and nick-stuph.

If you want to use it, here are the directions:

1) Press the Map Header in your trigger-list in the trigger editor. (It's at the top of the trigger-list, displays the name of the map).
2) CnP Graters' Complete API into the main Custom Script textbox. If you're already using the header for sumtin, it doesn't matter, just paste this below or above it.
3) Now. Create two triggers somewhere. Name them Save and Load (or whatever you want). No event. Go to "Edit->Convert To Custom Script" for them both. Copy the "CONTENTS" of the function called save here above, into the function that has "Actions" in its name in the Save trigger.
4) Do the same with the contents of the load function.
5) Go to the variable editor.
6) Create 6 variables, 4 Integer vars, 1 Player var and 1 String var. Name them this in the order as they come (first 4 integer vars, then a player var, then the string var). TempValue1, TempValue2, TempValue3, TempResult, TempPlayer, TempPassword.
EDIT: I forgot one variable (hope it's the last one). Called "CharMap" and is a string. Make it have a initial value of the following (or set it to the following in a initiation trigger): "ABCDEFGHJKLMNPQRSTUVWXYZ23456789" (or whatever you want. This has got the following char removed out of the alphabet: I, 1, O, 0)
7) Save your map. Pray to your god of choice for WE not to complain about any compile bugs :X. If it finishes saving then move to 8, if it complaints, you can feel free to post it here.
8) Close down your map.
9) Reopen it.
10) NOW... for the fun part. Now you can go on, and do your real saving/loading triggers.
11) In the saving trigger. Set TempPlayer to the player who is saving. Set TempValue1 to the first value to store, TempValue2 to the second, and TempValue3 to the third. After these lines, you do "Trigger - Execute (or is it Run?) Save". After that line, TempPassword will be storing your password, so you can feel free to show it to your player, or doing some SubString actions on it to add in a "-" if you like.
12) In the loading trigger. You set TempPlayer to the player who is loading. Set TempPassword to the inputted message (if it's properly formatted, there can be no "-"'s in it). Then do: "Trigger - Execute Load". After that line, TempResult will store if the password was legit (if it is 0, the password is ok, and it extracted all the values allright. If it's 1, it had a bad CheckSum. if it was 2, it was just plain wrong.). If TempResult is storing 0, then TempValue1, TempValue2 and TempValue3 will be storing the three values.

VOILA!, there it is!

Anyhow, you can feel free to change any of the names of the variables if you like, but then you also have to Find-Replace their references in the code I pasted above.

Also, if you don't like any of this, that API includes....what you originally asked for ;). "Name2IntHashFunction"... You still have to know how to use it though, heh.

Anyhow, i'm done.

Cubasis
04-18-2004, 05:06 AM#12
The Gearhead
First of all: I'm a dick, and an arrogant one. I wont use other people's stuff. I will ask for help, but dont expect me to copy paste some solution. Especially if I dont understand it.


I'm in the beginners side of the pool, and I wont stop until I'm all the way to the deep end.

So, please, just bear with me and answer my questions about jass.

Question:

Why the **** is JASS so word oriented, unlike Java... as in, a Java for loop is a for ( i > 0, i <32; i++) sort of ordeal... while in JASS its
set bj_ForLoopAIndex = 1
set bj_ForLoopAIndexEnd = 8
loop
exitwhen

blah blah blah. Wtf?
04-18-2004, 05:20 AM#13
Cubasis
Eh, if you compare everything in JASS with JAVA you'll get seriously confused.

Those loops you're looking at in JASS are not normal, these are the GUI loops. And they're not word-oriented, these are variables. And it doesn't matter if a variable is named: bj_ForLoopAIndex or i. This is what blizzard named their GUI stuff to make it easy to comprehend.

Anyhow, since we're on it, let's compare JAVA loops with JASS loops.

JAVA:
for(int i = 0;i < 32;i++)
for(DoAtStart;condition;DoAtEachIteration) <-- this is the syntax.

Now, first to answer your question. "i++" is short for: "i = i + 1" (or: "set i = i + 1" in JASS). There is no JASS version of this, so get used to writing it the longer way.

The difference between JASS and most languages in loops..is that the exit-condition must be "true" for it to exit the loop in JASS, in other languages, it must be wrong to exit the loop. That is, in JASS, it "exit when's" a condition is true, in other languages it loops "while" a condition is true).

So here is the loop syntax in JASS:

loop
exitwhen <condition>
<actions>
endloop

The exitwhen line can be anywhere inside the loop. For a loop that does the same thing as the for-loop above it would be like this.

set i = 0
loop
exitwhen i >= 32
<actions>
set i = i + 1
endloop

Note that you must have defined that "i" integer variable at the start of your function for that to work, like this:

local integer i (optional: " = 0")


Anyhow. I'm tired, and I just spent a half an hour writing that uber-solution for ya in a language that even a complete Triggering noob would understand....... So, if you don't like it becouse you don't understand everything in it, then fine, I don't really care. But then it'll take you many many more hours (considering your current knowledge) to get to a point where you can write a good enough algorithm like this in JASS.

So... have fun.

Cubasis
04-18-2004, 08:58 AM#14
Vidstige
Jass is unfortunately not as friendly as Java. With some efforts (and a lot of swearing) it can be learned to live with though. This AI Script Tutorial includes a few sections of Jass theory which might be helpful (look at table of contents in first post).

If you really hate writing stuff the long way (as one need to in Jass) you might want to dive into the precompiler discussion...
04-18-2004, 01:49 PM#15
jmoritz
I don't really understand why you are asking about java, when you want to learn jass. Are you trying to learn both languages at the same time?

And I strongly advise you to use Grater's algorithm. If you don't, expect this little problem to take you weeks (considering you current knowledge). Even an experienced programmer would need at least a day to program Grater's algorithm.