Nestharus
o-o
- Reaction score
- 83
JASS:
//Requires
// BigInt hiveworkshop.com/forums/jass-functions-413/system-bigint-188973/
// Base hiveworkshop.com/forums/submissions-414/snippet-base-188814/
// Ascii wc3c.net/showthread.php?t=110153
// Table hiveworkshop.com/forums/jass-functions-413/snippet-new-table-188084/
// KnuthChecksum hiveworkshop.com/forums/1846246-post343.html
// Scrambler hiveworkshop.com/forums/submissions-414/snippet-salt-189766/
library NumberEncrypter uses BigInt, KnuthChecksum, Scrambler
/***********************************************************************
*
* Security Details
*
* - Player Unique Base
* - Player Unique Shuffling
* - Player Unique Knuth Checksum
*
***********************************************************************
*
* function EncryptNumberVersion takes BigInt number, integer security, integer shuffles, integer forPlayerId, string playerSalt, real checksumVariance, integer maxVersion, integer ver returns string
* - Encrypts number of version
*
* -> maxVersion is the maximum possible version that number can be
* -> version is the version of the number
*
* function EncryptNumber takes BigInt number, integer security, integer shuffles, integer forPlayerId, string playerSalt, real checksumVariance returns string
* - Encrypts a BigInt given max security, shuffles, and player id
*
* -> security is the maximum value the security can be. Bigger means more secure but larger codes.
* -> 6-7 digits is usually good here
*
* -> shuffles is how many times to shuffle the number (make it impossible to read it)
* -> 3 shuffles is good for smaller numbers (maybe 15-20 char codes)
* -> 1 shuffle is good for larger (more than 20 chars)
* -> if this function freezes the game for a while, lower the amount of shuffles
*
* -> the player id is the id of the player to encrypt the value for (GetPlayerId(player))
*
* -> playerSalt refers to a string to be appended to the player's name when generating a unique checksum for that
* -> player (close to original checksum value).
*
* -> checksumVariance is how little the checksum can vary. The smaller this value, the more variance. The larger,
* -> the less variance. .85 is a good number.
*
* function GetLastDecryptedVersion takes nothing returns integer
* - Retrieves the last version that was decrypted out of a number (call after DecryptNumberVersion)
*
* function DecryptNumberVersion takes string c, Base base, integer security, integer shuffles, integer forPlayerId, string playerSalt, real checksumVariance, integer maxVersion returns BigInt
* - Decrypts a BigInt and its version and returns 0 if version was bad
* function DecryptNumber takes string c, string encryptionKey, integer security, integer shuffles, integer forPlayerId, string playerSalt, real checksumVariance returns BigInt
* - Decrypts a BigInt given its base, security, shuffles, and player id
* - Returns 0 if bad number
*
***********************************************************************/
globals
private Table array bases
private Table array checksums
private string array names
endglobals
private function GetPlayerBase takes Base base, integer pid returns Base
local string b
local BigInt i
if (not bases[pid].has(base)) then
set b=base.string
set i=BigInt.convertString(base.string,Base[SubString(b,1,2)+SubString(b,0,1)+SubString(b,2,base.size)])
call Scramble(i,pid,3,i.base,true)
set bases[pid][base]=Base[i.toString()]
call i.destroy()
endif
return bases[pid][base]
endfunction
private function GetPlayerChecksum takes integer checksum, integer pid, string playerSalt, real variance returns integer
local integer ch
local integer min
local integer range
set checksum=checksum+1
if (not checksums[pid].has(checksum)) then
set ch=StringHash(StringCase(names[pid]+playerSalt,false))
if (0>ch) then
set ch=-ch
endif
set min=R2I(checksum*variance)
set range=checksum-min
set ch=ch-ch/range*range+min
set checksums[pid][checksum]=ch
return ch
endif
return checksums[pid][checksum]
endfunction
function EncryptNumberVersion takes BigInt number, integer security, integer shuffles, integer forPlayerId, string playerSalt, real checksumVariance, integer maxVersion, integer ver returns string
local integer s
set security=GetPlayerChecksum(security,forPlayerId,playerSalt,checksumVariance) //get player unique security
set number.base=GetPlayerBase(number.base,forPlayerId) //get player unique base
//apply security
set s=GetKnuthChecksum(number,security)
call number.multiply(security+maxVersion)
call number.add(s+ver,0)
//apply player unique shuffle
call Shuffle(number,forPlayerId,shuffles)
//return number as string
return number.toString()
endfunction
function EncryptNumber takes BigInt number, integer security, integer shuffles, integer forPlayerId, string playerSalt, real checksumVariance returns string
local integer s
set security=GetPlayerChecksum(security,forPlayerId,playerSalt,checksumVariance) //get player unique security
set number.base=GetPlayerBase(number.base,forPlayerId) //get player unique base
//apply security
set s=GetKnuthChecksum(number,security)
call number.multiply(security)
call number.add(s,0)
//apply player unique shuffle
call Shuffle(number,forPlayerId,shuffles)
//return number as string
return number.toString()
endfunction
globals
private integer v = 0
endglobals
function GetLastDecryptedVersion takes nothing returns integer
return v
endfunction
function DecryptNumberVersion takes string c, Base base, integer security, integer shuffles, integer forPlayerId, string playerSalt, real checksumVariance, integer maxVersion returns BigInt
//convert to BigInt using player unique base
local BigInt number = BigInt.convertString(c,GetPlayerBase(base,forPlayerId))
//if converted
if (0!=number) then
//retrieve player unique security
set security=GetPlayerChecksum(security,forPlayerId,playerSalt,checksumVariance)
//remove player unique shuffle
call Unshuffle(number, forPlayerId, shuffles)
//retrieve version out of checksum
set v = number.divide(security+maxVersion) - GetKnuthChecksum(number, security)
//if version is out of bounds, return 0
if (v<1 or v>maxVersion) then
call number.destroy()
set v = 0
return 0
endif
endif
return number
endfunction
function DecryptNumber takes string c, Base base, integer security, integer shuffles, integer forPlayerId, string playerSalt, real checksumVariance returns BigInt
//convert to BigInt using player unique base
local BigInt number = BigInt.convertString(c,GetPlayerBase(base,forPlayerId))
//if converted
if (0!=number) then
//retrieve player unique security
set security=GetPlayerChecksum(security,forPlayerId,playerSalt,checksumVariance)
//remove player unique shuffle
call Unshuffle(number, forPlayerId, shuffles)
//if security doesn't match up, return 0
if (number.divide(security) != GetKnuthChecksum(number, security)) then
call number.destroy()
return 0
endif
endif
return number
endfunction
private module I
private static method onInit takes nothing returns nothing
local integer i=11
loop
if (GetPlayerSlotState(Player(i))==PLAYER_SLOT_STATE_PLAYING and GetPlayerController(Player(i))==MAP_CONTROL_USER) then
set names<i>=GetPlayerName(Player(i))
endif
set bases<i>=Table.create()
set checksums<i>=Table.create()
exitwhen 0==i
set i=i-1
endloop
endmethod
endmodule
private struct N extends array
implement I
endstruct
endlibrary
</i></i></i>
Working Demo
JASS:
struct T extends array
private static method init takes nothing returns nothing
local Base b=Base["0123456789abcdefghijklmnopqrstuvwxyz"]
local NumberStack c = NumberStack.create(b)
local string m
call c.push(10,10)
call c.push(20,20)
call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,I2S(BigInt(c).toInt()))
set m=EncryptNumber(c,1000000,3,0,"hello world",.85)
call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,m)
call c.destroy()
set c=DecryptNumber(m,b,1000000,3,0,"hello world",.85)
if (0!=c) then
call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,I2S(BigInt(c).toInt()))
else
call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,"INVALID")
endif
call DestroyTimer(GetExpiredTimer())
endmethod
private static method onInit takes nothing returns nothing
call TimerStart(CreateTimer(),0,false,function thistype.init)
endmethod
endstruct