Avatar billede angelenglen Nybegynder
06. januar 2012 - 16:21 Der er 12 kommentarer og
1 løsning

Krypter/dekrypter tal, til fast længde streng

Jeg har brug for at kunne kryptere/dekryptere en række fortløbende tal, men resultatet skal have samme længde og være alphanumerisk.
(0-9, A-Z) (case insensitive)

kilde-tallet vil være mellem 1 og 2.147.483.647, startende med 1, 2, 3 osv.
Hvis max-værdien er lavere kan det også gå, dog ikke lavere end 729.000.000 - det er ok hvis det gør opgaven lettere.

eksempel:
tallet 333 krypteres til 4f6u8dd
strengen 4f6u8dd dekrypteres til 333

resultat-strengen skal helst være mellem 6 og 8 karakterer lang, men skal være samme længde hver gang.
Jo kortere jo bedre.

Det skal helst også være sådan at resultat-strengene ikke ligner hinanden for meget - hvis fx 333 bliver til 4f6u8dd, så bør 334 og 335 ikke blive til 4f6u8de og 4f6u8df fordi det vil gøre det for let at kunne fake en værdi på den måde.

Eftersom det skal kunne dekrypteres, må der ikke være noget data-tab i processen, så fx at SHA1 eller MD5 hash'e det, og tage de sidste 6 karakterer dur ikke, fordi det ikke vil kunne dekrypteres, og det vil ikke nødvendigvis være unikt.

Målet er ud fra et database-id at kunne generere en unik kode, der kan dekrypteres og resultere i det oprindelige id.

Håber det giver mening :-)
Avatar billede arne_v Ekspert
06. januar 2012 - 16:36 #1
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
Avatar billede angelenglen Nybegynder
06. januar 2012 - 16:47 #2
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?
Avatar billede erikjacobsen Ekspert
06. januar 2012 - 16:57 #3
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.
Avatar billede angelenglen Nybegynder
06. januar 2012 - 16:59 #4
@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.
Avatar billede arne_v Ekspert
06. januar 2012 - 17:02 #5
Dit interval passer ind i en 32 bit integer. 32 bit = 4 binaere bytes.

Hvad programmerer du i?
Avatar billede erikjacobsen Ekspert
06. januar 2012 - 17:06 #6
Der kan være gengangere, ja, men du gør feltet unikt, og genererer en ny hvis der er fejl ved indsættelse.
Avatar billede Slettet bruger
06. januar 2012 - 21:06 #7
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?
Avatar billede clausc Nybegynder
09. januar 2012 - 09:46 #8
Mht bytes <-> string, så kan base16 (aka Hex) eller base32 overvejes.
Avatar billede arne_v Ekspert
15. januar 2012 - 04:04 #9
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.
Avatar billede arne_v Ekspert
15. januar 2012 - 04:07 #10
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);
        }
    }
}
Avatar billede arne_v Ekspert
15. januar 2012 - 04:08 #11
Note:

stor a => langsom dekryptering

lille a => ikke helt random i high end
Avatar billede angelenglen Nybegynder
05. februar 2012 - 23:22 #12
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.
Avatar billede arne_v Ekspert
06. februar 2012 - 00:10 #13
ok
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester