Integer ID obfuscation techniques

后端 未结 10 1577
萌比男神i
萌比男神i 2020-12-06 07:14

I\'m looking for an easy and reversible method of obfuscating integer IDs. Ideally, I\'d want the resulting obfuscation to be at most eight characters in length and non-seq

相关标签:
10条回答
  • 2020-12-06 07:15

    I realize this is an old post, but I thought it might be helpful to post my technique for obfuscating integer ids

    Cons: does use more than 8 characters, only good for id values under 33 million

    Pros: does not require a key to de-obfuscate, URL/cookie friendly, generates a different value every time which makes it harder to break, no collisions, includes a checksum feature to eliminate random / brute force attempts to break (one issue that the above post do not address, is people trying to "scrape" your site. If I see a url ending in id=123 I know I can try id=124 etc... to get additional data, this is why some of the XOR examples are likely not a good idea)

    I would recommend tweaking this a bit (which I've done for mine) as I don't think you should ever use a publically published obfuscation technique, but it is a good place to start.

    Happy coding!

        public static string ObfuscateId(int id)
        {
            try
            {
                string rtn;
                int sid = id + 279;
                int xm = sid * 3;
                int xl = xm.ToString().Length + 10;
                string sc = xl.ToString().Substring(1, 1);
                string fc = xl.ToString().Substring(0, 1);
                string csum = sid.ToString().Substring(sid.ToString().Length - 3);
                rtn = Guid.NewGuid().ToString().Replace("-", "").ToLower();
                rtn = sc + rtn.Substring(2, 26) + fc;
                rtn = rtn.Remove(4, 3).Insert(4, csum);
                rtn = rtn.Remove(xl, (xl - 10)).Insert(xl, xm.ToString());
                rtn = rtn.Replace('1', 'g');
                rtn = rtn.Replace('2', 'h');
                rtn = rtn.Replace('3', 'i');
                rtn = rtn.Replace('4', 'w');
                rtn = rtn.Replace('5', 'y');
                rtn = rtn.Replace('6', 'u');
                rtn = rtn.Replace('7', 'z');
                rtn = rtn.Replace('8', 'l');
                rtn = rtn.Replace('9', 'v');
                rtn = rtn.Replace('0', 'n');
                rtn = rtn.Replace('c', 'j');
                rtn = rtn.Replace('d', 'p');
                rtn = rtn.Replace('f', 'q');
    
                return rtn.ToUpper();
            }
            catch
            {
                return "ERROR BAD ID";
            }
        }
    
        public static int DeObfuscateId(string obtxt)
        {
            try
            {
                string rtn;
                int id;
    
                rtn = obtxt.ToLower();
                rtn = rtn.Replace('g', '1');
                rtn = rtn.Replace('h', '2');
                rtn = rtn.Replace('i', '3');
                rtn = rtn.Replace('w', '4');
                rtn = rtn.Replace('y', '5');
                rtn = rtn.Replace('u', '6');
                rtn = rtn.Replace('z', '7');
                rtn = rtn.Replace('l', '8');
                rtn = rtn.Replace('v', '9');
                rtn = rtn.Replace('n', '0');
                rtn = rtn.Replace('j', 'c');
                rtn = rtn.Replace('p', 'd');
                rtn = rtn.Replace('q', 'f');
    
                string sc = rtn.Substring(0, 1);
                string fc = rtn.Substring(rtn.Length - 1);
                int xl = int.Parse(fc + sc);
                int mv = int.Parse(rtn.Substring(xl, (xl - 10)));
                int sid = mv / 3;
                id = sid - 279;
                string csum = sid.ToString().Substring(sid.ToString().Length - 3);
                string xsum = rtn.Substring(4, 3);
    
                if (csum!=xsum)
                {
                    return -99999;
                }
    
                return id;
            }
            catch
            {
                return -99999;
            }
        }
    
    }
    
    0 讨论(0)
  • 2020-12-06 07:15

    Just get a MD5/SHA1 hash of the integer's byte representation. You are guaranteed not to get collisions.

    0 讨论(0)
  • 2020-12-06 07:20

    I realise this was asked 7 months ago so you will have found a solution by now, but solution I've come across is a combination of Skip32/Skipjack cipher + a base32 encoding. The perl example (since that's where I know of one) shows:

    use Crypt::Skip32::Base32Crockford;
    my $key    = pack( 'H20', "112233445566778899AA" ); # Always 10 bytes!
    my $cipher = Crypt::Skip32::Base32Crockford->new($key);
    my $b32    = $cipher->encrypt_number_b32_crockford(3493209676); # 1PT4W80
    my $number = $cipher->decrypt_number_b32_crockford('1PT4W80'); # 3493209676
    

    I don't know of a c# implementation, but a perl one is http://search.cpan.org/perldoc?Crypt::Skip32::Base32Crockford and the two constituent parts for a ruby one are https://github.com/levinalex/base32 and https://github.com/patdeegan/integer-obfuscator. Between the two of them you should be able to port it to any language you need.

    0 讨论(0)
  • 2020-12-06 07:29

    Update May 2017

    Feel free to use (or modify) the library I developed, installable via Nuget with:

    Install-Package Kent.Cryptography.Obfuscation

    This converts a non-negative id such as 127 to 8-character string, e.g. xVrAndNb, and back (with some available options to randomize the sequence each time it's generated).

    Example Usage

    var obfuscator = new Obfuscator();
    string maskedID = obfuscator.Obfuscate(15);
    

    Full documentation at: Github.


    Old Answer

    Just adding variety to an old answer. Perhaps someone will need it. This is an obfuscation class I made sometime back.

    Obfuscation.cs - Github

    You can use it by:

    Obfuscation obfuscation = new Obfuscation();
    string maskedValue = obfuscation.Obfuscate(5);
    int? value = obfuscation.DeObfuscate(maskedValue);
    

    Cheers, hopefully it can be of use.

    0 讨论(0)
  • 2020-12-06 07:30

    In case other people are interested, somebody adapted a 32-bit block cipher a few years back that's especially useful for this task.

    • http://www.qualcomm.com.au/PublicationsDocs/skip32.c

    There is also Perl and Ruby port of the above available:

    • https://github.com/gitpan/Crypt-Skip32
    • https://github.com/patdeegan/integer-obfuscator

    If you need the result in 8 characters or less, you can use a hex or base64 representation.

    0 讨论(0)
  • 2020-12-06 07:30

    Nice project for handling that with libraries in most languages: http://hashids.org/

    0 讨论(0)
提交回复
热议问题