1 og 2.147.483.647 er 4 binaere bytes
4 binaere bytes kan krypteres med enhver standard krypterings algoritme
hvis det er OK at kryptere flere tal af gangen bruger du bare din foretrukne krypterings algoritme
hvis hvert tal skal krypteres helt separat skal du have fat i en algoritme med en block size paa 32 bit
output fra kryptering er (hvis block size problemet er loest) ogsaa 4 binaere bytes
4 binaere bytes kan transformeres til 6 tegn med 36 forskellige muligheder
Om de krypteres sammen eller hver for sig, er ligemeget for mig, så længe jeg kan komme tilbage til udgangspunktet igen efterfølgende.
Jeg kan ikke lige gennemskue hvordan jeg kommer fra fx tallet 555 til 4 binære bytes?
Må jeg vende dit problem om, og foreslå et ekstra felt i din tabel, ved siden af dit id. Det indeholder så dine 6-8 tegn, evt genereret ud fra en hash-funktion, og bruges til opslag.
@Erik: Det kan jeg desværre ikke bruge, det er vigtigt at resultat-strengen er unik i forhold til de andre der kan genereres.
Derfor går en hash ikke, da det ikke er unikt hvis jeg fx tager de sidste 6 karakterer fra en hash-værdi på 32 karakterer.
Der kan sagtens være mange gengangere på den måde.
Dit interval passer ind i en 32 bit integer. 32 bit = 4 binaere bytes.
Hvad programmerer du i?
Der kan være gengangere, ja, men du gør feltet unikt, og genererer en ny hvis der er fejl ved indsættelse.
Hvad er formålet med krypteringen/dekrypteringen (hvad vil du beskytte dig imod)? Og hvorfor skal krypteringen begrænses til max 8 tegn (og er det kun tilladt at bruge a-z og 0-9)? Har du behov for at kunne dekryptere tallet, eller skal det bare bruges til at sammenligne et ukrypteret id med et krypteret?
Mht bytes <-> string, så kan base16 (aka Hex) eller base32 overvejes.
Efter at have overvejet problem naermere vil jeg konkludere at enhver algoritme hvor krypteringen af et enkelt id ikke er uafhaengigt af andre id'er ikke duer - hvis man sletter en raekke goer man et antal raekker ulaeselige - og det er ikke godt design ikke at hav emulighed for at slette raekker (ogsaa selvom det i de fleste tilfaelde er bedre med et deleted flag).
Det udlukker stort set alle respektable krypterings algoritmer.
Naar vi saa skal ned i det mindre respektable er her mit bud (eksempel i Java):
import java.util.ArrayList;
import java.util.List;
public class IdObfuscate {
private class LCG {
private long a;
private long c;
private long m;
private LCG(long a, long c, long m) {
this.a = a;
this.c = c;
this.m = m;
}
public LCG(int a, int c) {
this(4 * a + 1, 2 * c + 1, 1L << 31);
}
public int next(int v) {
long v2 = 0xFFFFFFFFL & v;
return (int)((a * v2 + c) % m);
}
public int prev(int v) {
long v2 = 0xFFFFFFFFL & v;
long res;
int k = 0;
do {
res = (v2 - c + k * m) / a;
k++;
} while(res < 0 || next((int)res) != v2);
return (int)res;
}
}
private class Encoder {
private String cs;
public Encoder(String cs) {
this.cs = cs;
}
public String encode(int v) {
long v2 = 0xFFFFFFFFL & v;
String res = "";
for(int i = 0; i < 6; i++) {
res = cs.charAt((int) (v2 % cs.length())) + res;
v2 /= 36;
}
return res;
}
public int decode(String s) {
long res = 0;
for(char c : s.toCharArray()) {
res = res * 36 + cs.indexOf(c);
}
return (int)res;
}
}
private LCG lcg;
private Encoder enc;
private int key;
public IdObfuscate(int a, int c, String cs, int key) {
lcg = new LCG(a, c);
enc = new Encoder(cs);
this.key = key;
}
public String encode(int id) {
return enc.encode(key ^ lcg.next(lcg.next(lcg.next(lcg.next(id)))));
}
public int decode(String id) {
return lcg.prev(lcg.prev(lcg.prev(lcg.prev(key ^ enc.decode(id)))));
}
public List<String> encode(List<Integer> ids) {
List<String> res = new ArrayList<String>();
for(int id : ids) {
res.add(encode(id));
}
return res;
}
public List<Integer> decode(List<String> ids) {
List<Integer> res = new ArrayList<Integer>();
for(String id : ids) {
res.add(decode(id));
}
return res;
}
public static void main(String[] args) {
//IdObfuscate obf = new IdObfuscate(2048, 55555555, "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", 12345);
//IdObfuscate obf = new IdObfuscate(1234, 55555555, "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", 12345);
IdObfuscate obf = new IdObfuscate(77, 55555555, "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", 12345);
List<Integer> ids = new ArrayList<Integer>();
ids.add(1);
ids.add(2);
ids.add(4);
ids.add(5);
ids.add(6);
ids.add(8);
ids.add(9);
ids.add(10);
ids.add(12);
ids.add(13);
for(int id : ids) {
System.out.println(id);
}
List<String> obfids = obf.encode(ids);
for(String obfid : obfids) {
System.out.println(obfid);
}
List<Integer> xids = obf.decode(obfids);
for(int id : xids) {
System.out.println(id);
}
}
}
Note:
stor a => langsom dekryptering
lille a => ikke helt random i high end
Det er meget brugbart arne_v, det kan jeg sagtens bruge.
Jeg skal godt nok bruge det i VB.Net, men har fået en kammerat til at hjælpe lidt med at få det omskrevet, og det har virket som forventet!
Du må meget gerne lægge et svar - jeg beklager jeg ikke har reageret før, men jeg har været på ferie.