Simple algorithm for mixing/obfuscating a string with pre-defined chars

后端 未结 5 680
北恋
北恋 2021-01-31 05:39

I have a string as follows:

  • Its length is 10.
  • It represents base 36 and as such includes digits and uppercase letters.
  • The origin of the st
5条回答
  •  野性不改
    2021-01-31 06:10

    Are you looking for something like this?

    import java.util.Locale;
    
    public class Obfuscate {
    
        //adjust to suit:
        final static int feistelRounds = 4;
        final static int randRounds = 4;
        final static int seed = 12345;
    
        // modulus for half a string:
        final static int mod = 60466176; //36^5
    
        private static int f (int x) {
            // http://en.wikipedia.org/wiki/Linear_congruential_generator
            final int a = 12+1;
            final int c = 1361423303;
            x = (x + seed) % mod;
            int r = randRounds;
            while (r-- != 0) {
                x = (a*x+c) % mod;
            }
            return x;
        }
    
        public static String obfuscate (int i) {
            int a = i / mod;
            int b = i % mod;
            int r = feistelRounds;
            while (r-- != 0) {
                a = (a + f(b)) % mod;
                b = (b + f(a)) % mod;
            }
            return pad5(Integer.toString(a, 36)) + pad5(Integer.toString(b, 36));
        }
    
        public static int illuminate (String s) {
            int a = Integer.valueOf(s.substring(0,5),36);
            int b = Integer.valueOf(s.substring(5,10),36);
            int r = feistelRounds;
            while (r-- != 0) {
                b = (b - f(a)) % mod;
                a = (a - f(b)) % mod;
            }
            // make the modulus positive:
            a = (a + mod)%mod;
            b = (b + mod)%mod;
    
            return a*mod+b;
        }
    
        public static String pad5(String s) {
            return String.format("%5s", s).replace(' ', '0').toUpperCase(Locale.ENGLISH);
        }
    
        public static String pad10(String s) {
            return String.format("%10s", s).replace(' ', '0').toUpperCase(Locale.ENGLISH);
        }
    
        // demonstration
        public static void main(String[] args) {
            for (int i = 0; i<20; i++) {
                System.out.printf("%08d -> %s -> %08d\n", i, obfuscate(i), illuminate(obfuscate(i)));
            }
        }
    }
    

    output:

    00000000 -> P2TH9ZW2VI -> 00000000
    00000001 -> G47GI9ZR9S -> 00000001
    00000002 -> 75LFRK3FO2 -> 00000002
    00000003 -> Y6ZF0U742C -> 00000003
    00000004 -> P8DE94ASGM -> 00000004
    00000005 -> G9RDIEEGUW -> 00000005
    00000006 -> 7B5CROI596 -> 00000006
    00000007 -> YCJC0YLTNG -> 00000007
    00000008 -> PDXB98PI1Q -> 00000008
    00000009 -> GFBAIIT6G0 -> 00000009
    00000010 -> 7GP9RSWUUA -> 00000010
    00000011 -> YI39030J8K -> 00000011
    00000012 -> PJH89D47MU -> 00000012
    00000013 -> GKV7IN7W14 -> 00000013
    00000014 -> 7M96RXBKFE -> 00000014
    00000015 -> YNN607F8TO -> 00000015
    00000016 -> PP159HIX7Y -> 00000016
    00000017 -> GQF4IRMLM8 -> 00000017
    00000018 -> 7RT3R1QA0I -> 00000018
    00000019 -> YT730BTYES -> 00000019
    

    Basically, this is a toy, totally non-secure, though fun to write, encryption algorithm. (Encryption really is what you asked for --- output that's unintelligible to others but reversible by you.) I've implemented a Feistel network (http://en.wikipedia.org/wiki/Feistel_cipher) using a simple prng as the f function.

    The results are pretty, though, right? DES, as suggested above, would be more secure. But, if you'd rather reinvent the wheel (I struggle with that impulse a bit myself) and real security isn't a concern, this is a reasonable place to start. BTW, DES is also based on a Feistel network.

    Actually, a non-encryption-based solution might exist, depending on your requirements. If this is, say, a coupon code that needs to be checked but not guessed, I'd just create a table in my database relating the id to a randomly-generated 10 character code (or add the code column to an existing table of coupons) and look them up as they come in. This would of course require the encoding and recovering software to have access to the same database, or to be able to communicate.

提交回复
热议问题