4

I'm not sure what this is called, which is why I'm having trouble searching for it.

What I'm looking to do is to take numbers and convert them to some alphanumeric base so that the number, say 5000, wouldn't read as '5000' but as 'G4u', or something like that. The idea is to save space and also not make it obvious how many records there are in a given system. I'm using php, so if there is something like this built into php even better, but even a name for this method would be helpful at this point.

Again, sorry for not being able to be more clear, I'm just not sure what this is called.

coip
  • 1,312
  • 16
  • 30
mrpatg
  • 10,001
  • 42
  • 110
  • 169
  • You might want to take a look at [hashids](https://github.com/ivanakimov/hashids.php). – Gottlieb Notschnabel Mar 25 '15 at 06:52
  • You might find [`Alphabet::convert($number, Alphabet::DECIMAL, Alphabet::ALPHANUMERIC)`](https://github.com/delight-im/PHP-BaseConvert) useful, which can also be used with `Alphabet::ALPHANUMERIC_HUMAN` or any custom alphabet you specify. It works on arbitrarily large numbers. – caw Aug 21 '19 at 13:13

5 Answers5

8

You want to change the base of the number to something other than base 10 (I think you want base 36 as it uses the entire alphabet and numbers 0 - 9).

The inbuilt base_convert function may help, although it does have the limitation it can only convert between bases 2 and 36

$number = '5000';
echo base_convert($number, 10, 36); //3uw
Yacoby
  • 54,544
  • 15
  • 116
  • 120
  • @Patrick this would also be my way to go. Just remember that you're not really hiding/protecting anything in your site by cloaking the numbers. And anyone can easily figure out that you are base36'ing the numbers. But this would be the way to go. Code examples here: http://www.tonymarston.net/php-mysql/converter.html – Frankie Jun 06 '10 at 18:29
  • And PHP docs for base_covert have a comment with "A simple function to convert an int to any base." That way i can expand it to treat a-z and A-Z as distinct cases, giving me 62 district options instead of 36. – Rudi Mar 31 '15 at 18:47
5

Funnily enough, I asked the exact opposite question yesterday.

The first thing that comes to mind is converting your decimal number into hexadecimal. 5000 would turn into 1388, 10000 into 2710. Will save a few bytes here and there.

You could also use a higher base that utilizes the full alphabet (0-Z instead of 0-F) or even the full 256 ASCII characters. As @Yacoby points out, you can use base_convert() for that.

As I said in the comment, keep in mind that this is not an efficient way to mask IDs. If you have a security problem when people can guess the next or previous ID to a record, this is very poor protection.

Community
  • 1
  • 1
Pekka
  • 442,112
  • 142
  • 972
  • 1,088
  • 1
    there are no security implications, just cosmetic, base_convert is the answer that looks like itll work. Thanks all for the help and insight though! – mrpatg Jun 06 '10 at 18:28
  • http://php.net/manual/en/function.base-convert.php#105990 will also allow for expanding number of characters used, for example upper-case ones as well. – Rudi Mar 31 '15 at 18:48
  • While a *byte* can represent 256 possible values, *ASCII* only has 128 characters. – caw Aug 17 '19 at 22:29
2

dechex will convert a number to hex for you. It won't obfuscate how many records are in a given system, however. I don't think it will make it any more efficient to store or save space, either.

You'd probably want to use a 2 way crypt function if obfuscation is needed. That won't save space, either.

Please state your goals more clearly and give more background, because this seems a bit pointless as it is.

JAL
  • 21,295
  • 1
  • 48
  • 66
0

This might confuse more people than simply converting the base of the numbers ...

Try using signed digits to represent your numbers. For example, instead of using digits 0..9 for decimal numbers, use digits -5..5. This Wikipedia article gives an example for the binary representation of numbers, but the approach can be used for any numeric base.

Using this together with, say, base-36 arithmetic might satisfy you.

High Performance Mark
  • 77,191
  • 7
  • 105
  • 161
-1

EDIT: This answer is not really a solution to the question, so ignore it unless you are trying to hash a number.

My first thought we be to hash it using eg. md5 or sha1. (You'd probably not save any space though...)

To prevent people from using rainbow-tables or brute force to guess which number you hashed, you can always add a salt. It can be as simple as a string prepended to your number before hashing it.

md5 would return an alphanumeric string of exactly 32 chars and sha1 would return one of exaclty 40 chars.

mqchen
  • 4,195
  • 1
  • 22
  • 21
  • He'd obviously still **want** to know what the original number was. The idea is to save disc space, so it needs to be reversible. – Jan K. Jun 06 '10 at 18:24
  • Well, that wouldn't save any space (the opposite, actually) and you wouldn't be able to get the original number back from the hash. – JAL Jun 06 '10 at 18:25
  • Sorry, guess I misunderstood him. – mqchen Jun 06 '10 at 18:28