简体   繁体   中英

Encode and decode url message ID using php

I am trying to encode the message id of a php application and I cannot find a clear description on how to do so.

Basically I have a url for example - http://www.mymessager.com?messageID=1234

I want to have the system encode the message id for the url but do not change it in the database, for example - http://www.mymessager.com?messageID=38927648726894762345768

How can I do such a thing so that if someone goes to the encoded url the php will display http://www.mymessager.com?messageID=38927648726894762345768 in the address bar, but the script will pull message 1234 out of the database?

I know there have been similar questions out there, but I have not found one that talks about what I want to do (mostly is to clean the url).

Is this to avoid other users to open up other users private messages with messageID=4321 and so on? Because then this way is no way to go!

You should check that the user that is opening a message is actually allowed to do so.

If the messages is non private, and you just don't wan't people to incrementially view messages by modifying the number. Then you could add a 'messageKey' field to the database and setting random strings of a specified length. Example http://www.mymessager.com?messageKey=jadg23sf34lhs

Now just search in the DB for messages with that messageKey. Just remember to make sure that the messageKey is unique.

In this way you could also set the messageKey to something easy to remember, or SEO perhaps friendly. As long as it's unique.

I actually translated them to a string:

$consts = array(66016,57721, 42344,56714,76422);
define( 'BASE', 36 );
$to_encrypt = 5789;
// Generate a random seed value as an index of the constants
$seed = rand(0,count()-1);

// Add the constant the product of the seed and the to the value to be encrypted 
// (the multiplication just serves to create more noise)
$base_crypt = ( $consts[ $seed ] + $to_encrypt * ( $seed + 1 ) );

//SEE NOTES ON FLOATING POINT ISSUES IN PHP DOCS!
$encrypted = base_convert( BASE * $base_crypt + $seed, 10, BASE );

Then decrypt:

 $encrypted = base_convert( $_GET[ 'encrypted' ], BASE, 10 );
 $seed      = $encrypted % BASE;
 $decrypted = ( ( $encrypted - $seed )/BASE - $consts[ $seed ])/( $seed + 1 );

You will probably need to use bcadd and the like to an extent, but I have a production copy of this system and it works.

(I have to include a link to where I first published this).

if you're hashing (eg with md5) the value you can compare hashed values of id eg:

   $SQL = "SELECT * FROM `messages` WHERE MD5(ID) = '".$_GET['id']."'";

This is usually done by storing another ID for each entry in the database. If you don't want to go that route, you'll have to use a function that can convert to/from "public" id's. Like...

function toPublicId($id) {
  return $id * 1498158 + 825920496;
}

function toInternalId($publicId) {
  return ($publicId - 825920496) / 1498158;
}

or whatever. I sometimes use guaranteed unique alphanumeric ID's for public ID's, converting to/from them by converting to/from for instance base36 and a large multiplier + offset.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM