Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length

 
Advanced search

879052 Posts in 32956 Topics- by 24353 Members - Latest Member: kanki

May 23, 2013, 06:25:24 AM
TIGSource ForumsDeveloperTechnical (Moderators: Glaiel-Gamer, ThemsAllTook)Generating level unlock codes
Pages: [1]
Print
Author Topic: Generating level unlock codes  (Read 684 times)
st33d
Guest
« on: April 17, 2012, 03:05:29 AM »

I have a flash game which may transfer to a new url. I need to communicate to the next url a code (say a query string ?code=ASDFG) to start at the last unlocked level.

Of course I could just generate a bunch of random letters. I'm wondering what other methods might actually have the data in the code string, so I won't have to generate decks of codes, and so I could possibly transmit other information.

Any suggestions? (Any better than rot13 that is.)
Logged
Dacke
Level 10
*****


I have never been to Woodstock


View Profile
« Reply #1 on: April 17, 2012, 08:45:41 AM »

A common approach is to take some data (binary/string) and encode it as as an ASCII string. The most common approach is to use Base64 but ASCII85 is more efficient. Both of these give you ASCII characters that work in an URL.

Here is my favourite website for encoding and decoding Base64 strings:
http://ostermiller.org/calc/encode.html

But as mentioned, you can encode binary data for higher efficiency.

edit:
A drawback is that you often get '=' or '==' as padding at the end of the string.
My name is Dacke becomes TXkgbmFtZSBpcyBEYWNrZQ==

If you specifically want to encode a longer text, you can start by compressing the string to a binary format (~zip it) and then encode it to Base64.

But if you can encode your data as binary to begin with (for example sending numbers or bit-flags) you will get more information sent using a shorter string.
« Last Edit: April 17, 2012, 09:01:21 AM by Dacke » Logged

vegan • socialist • atheist • humanist • liberal • FOSSer
programmer • feminist • animal rights activist • pacifist • teetotaller
Dacke
Level 10
*****


I have never been to Woodstock


View Profile
« Reply #2 on: April 18, 2012, 07:21:25 AM »

Amendment:
The problem with equal signs at the end can easily be avoided. Just make sure to encode the right amount of data and no paddings will be needed.
https://en.wikipedia.org/wiki/Base64#Decoding_Base64_with_padding
Logged

vegan • socialist • atheist • humanist • liberal • FOSSer
programmer • feminist • animal rights activist • pacifist • teetotaller
st33d
Guest
« Reply #3 on: April 19, 2012, 05:57:52 AM »

I tried this, but the result ended in a code that went up in a predictable sequence.

In the end I just opted for as3crypto and used RC4 to get a url-safe code. And with the ability to set a key it means I can use this for future projects.

Seeing as getting it to work though was a nightmare (lots of misinformation on the internet) here's the code for extracting query string data and creating rc4 code chunks:

Code:
package com.nitrome.util {
import com.nitrome.ui.Key;
import flash.external.ExternalInterface;
import flash.utils.ByteArray;
import com.hurlant.util.Hex;
import flash.utils.ByteArray;
import com.hurlant.crypto.prng.ARC4;


/**
* Extract data from the query string
*
* @author Aaron Steed, nitrome.com
*/
public class QueryData {

public static var queryData:Object;

public static function getQueryData():void{
queryData = {};
if(ExternalInterface.available){

var url:String = ExternalInterface.call("document.location.search.toString");
if(url && url.indexOf("?") > -1){
var pairs:Array = url.split("?")[1].split("&");
var pairName:String;
var pairValue:String;

for(var i:int = 0; i < pairs.length; i++){
pairName = pairs[i].split("=")[0];
pairValue = pairs[i].split("=")[1];
queryData[pairName] = pairValue;
}
}
}
}

public static function encodeURLData(str:String, keyStr:String):String{
var byteArray:ByteArray = Hex.toArray(Hex.fromString(str));
var keyBytes:ByteArray = Hex.toArray(Hex.fromString(keyStr));
var rc4:ARC4 = new ARC4(keyBytes);
rc4.encrypt(byteArray);
return Hex.fromArray(byteArray);
}

public static function decodeURLData(str:String, keyStr:String):String{
var byteArray:ByteArray = Hex.toArray(str);
var keyBytes:ByteArray = Hex.toArray(Hex.fromString(keyStr));
var rc4:ARC4 = new ARC4(keyBytes);
rc4.decrypt(byteArray);
return Hex.toString(Hex.fromArray(byteArray));

}
}
}
Logged
Dacke
Level 10
*****


I have never been to Woodstock


View Profile
« Reply #4 on: April 19, 2012, 08:10:28 AM »

Good that you found a solution that works for you Smiley

I tried this, but the result ended in a code that went up in a predictable sequence.

Your OP post didn't really specify your requirements. But as I mentioned, you can take any binary data and run it through Base64/Ascii85 to get a valid URL String. Base64/Ascii85 are just efficient encodings from binary to URL-compatible strings. As such they do not try to obfuscate the data in any relevant way. So it is up to you to generate binary data that is obfuscated enough for your uses. Which can be done either by designing your own datatype that stores the data you need in a cryptic way. Or automatically by encrypting or compressing the data.

If you just want to turn a number into another number, you can manually implement something simple like RSA. Here is a short RSA example I wrote in python. It turns any number from 0 to 9795 into another 4-digit number.
Code:
def encode(integer):
    return str(((integer+2)**17)%9797).rjust(4, '0')

def decode(code):
    return (int(code)**3953)%9797-2

For example:
original -> encoded -> decoded
9288 -> 8611 -> 9288
9289 -> 8786 -> 9289
9290 -> 0505 -> 9290

edit: I posted a much faster solution three posts down


« Last Edit: April 19, 2012, 10:52:11 AM by Dacke » Logged

vegan • socialist • atheist • humanist • liberal • FOSSer
programmer • feminist • animal rights activist • pacifist • teetotaller
rivon
Level 10
*****



View Profile
« Reply #5 on: April 19, 2012, 08:55:55 AM »

Power of 3953 for decoding every number?
Logged
Dacke
Level 10
*****


I have never been to Woodstock


View Profile
« Reply #6 on: April 19, 2012, 09:06:12 AM »

Hehe, yes. It's just an example of what you can do. It depends on what you use it for. Client side it will be fine, serverside it could pose a problem. But server-side you can store a lookup table for it.
Logged

vegan • socialist • atheist • humanist • liberal • FOSSer
programmer • feminist • animal rights activist • pacifist • teetotaller
Dacke
Level 10
*****


I have never been to Woodstock


View Profile
« Reply #7 on: April 19, 2012, 10:48:59 AM »

Here is the same RSA solution, but with faster decryption (no huge powers). It also supports numbers up to 9866. The entire thing is based on stuff I learnt on Wikipedia today.

Code:
def encode(integer):
    return str(((integer+2)**17)%9869).rjust(4, '0')

def decode(code):
    m2 = int(code)**65%139
    return m2+47*(int(code)**33%71-m2)%71*139-2

example
i -> encode(i) -> decode(encode(i))
9845 -> 4483 -> 9845
9846 -> 2827 -> 9846
9847 -> 1443 -> 9847

edit: But you'd still end up with overflow in AS3 as it doesn't have support for BigInt. So.. nevermind. I mostly found it enjoyable to hack up my own RSA implementation.
« Last Edit: April 19, 2012, 10:57:36 AM by Dacke » Logged

vegan • socialist • atheist • humanist • liberal • FOSSer
programmer • feminist • animal rights activist • pacifist • teetotaller
Xienen
Level 2
**


Greater Good Games


View Profile WWW Email
« Reply #8 on: April 20, 2012, 06:47:18 PM »

I tend to use Tiny Encryption Algorithm aka TEA or XTEA to transform the data with a private key then, if the output needs to be unpredictable, I encrypt it again using a public key...finally I use my own number to character string transform(similar to RSA, Base64, etc) and interlace the public key into the encrypted data.  The result is a seemingly random data output that is still decryptable.
Logged

Owner/Programmer at Greater Good Games makers of Break Blocks
Currently developing It Hungers(Unity) and Swipe Attack(UDK)
Dacke
Level 10
*****


I have never been to Woodstock


View Profile
« Reply #9 on: April 20, 2012, 07:02:36 PM »

Your suggestion to use TEA/XTEA sounds good.

A few thoughts:

1. In what way is the output predictable after the private-key-encryption? Isn't the point of an encryption to generate unpredictable results?

2. RSA is an encryption algorithm (like TEA). Not a number->string converter (like Base64)

3. Instead of using your manual number->string converter, you may want to look into ASCII85. It has some nice optimality features.

Logged

vegan • socialist • atheist • humanist • liberal • FOSSer
programmer • feminist • animal rights activist • pacifist • teetotaller
Xienen
Level 2
**


Greater Good Games


View Profile WWW Email
« Reply #10 on: April 20, 2012, 07:31:50 PM »

I'm no cryptologist, so I'm no expert here

1. Encryption doesn't necessarily infer randomization, particularly when only using a private key.  The idea is that it's very difficult to crack without knowing the private key.  Usually it's the public key that causes the output to appear randomized, from my understanding, because it's often a randomly generated public key.

2. My bad, I haven't used RSA.

3. I use my own because it further adds a layer of unknown to someone staring at the final output of my algorithm.  Obviously that's just security by obscurity, but I like to think it helps a little Wink
Logged

Owner/Programmer at Greater Good Games makers of Break Blocks
Currently developing It Hungers(Unity) and Swipe Attack(UDK)
Dacke
Level 10
*****


I have never been to Woodstock


View Profile
« Reply #11 on: April 20, 2012, 07:53:18 PM »

1. Ah, I see. I should probably read up on cryptology.

3. ASCII85 allows you to use any 85 ASCII characters in any order. It just stores numbers in a radix 85 format, but it's up to you to decide the symbol for each digit.
Logged

vegan • socialist • atheist • humanist • liberal • FOSSer
programmer • feminist • animal rights activist • pacifist • teetotaller
Pages: [1]
Print
Jump to:  

Theme orange-lt created by panic