PHP: a shorter / hidden encoding for a URL embedded in another URL?

I am writing myself a script that basically allows me to send the url and two integer sizes in querystring of one receive request. I use base64 to encode it, but its pretty damn long, and I'm worried that the url might get too big.

Does anyone know an alternative, shorter way to do this? It must be available for decoding when it is received in a receive request, so md5 / sha1 is not possible.

Thank you for your time.


Edit: Sorry - I should have explained better: Well, on our site we show screenshots of websites that are published for viewing. We have our own thumbnail / screenshot server. I'm basically going to have an image tag containing an encoded string that stores the url to take a screenshot, and the width / height of the image. However, I do not want this to be a "raw text" for the world. Base64 can obviously be solved by anyone, but we don’t want your average Joe to collect the url. Actually I need to get: url, width, height in one GET request.

+6
php encoding get base64
source share
6 answers

URLs are not intended to send long lines of data encoded or not encoded. After a certain moment, when you are dealing with such large amounts of data that are sent through the URL, you should just start using POST or some kind of local memory. FYI, IE has a URL limit of 2038 characters.


EDIT: I don't understand anything. Why aren't you caching screenshots? It seems terribly resource-intensive when you have to take a new screenshot every time someone views a page with an IMG link to this URL.

Your audience may be small and resources are not a problem. However, if it is the other way around, and in fact it is a public website that will not scale very well. I know that I am going beyond your original question, but that will solve your question and much more.

Once the site is published, save the URL in some local storage, preferably in sql. I am going to continue this example as if you had chosen SQL, but, of course, your implementation is your choice. I would have a primary key, a url field and last_updated timestamp, and possibly a path to the image thumbnail.

Using local storage, you can now extract the image from the cached copy stored locally on the server, each time a page with a thumbnail is requested. A significant amount of resources are saved, and since there is a possibility that these websites will not be updated very often, you may have a cron or script task that runs every x minutes to update screenshots of the whole database. Now all you have to do is directly connect (again, it depends on your implementation) to the image, and not one of these huge lines of lines will be.

OR, just do the easy way and do it on the client side http://www.snap.com/

+3
source share

Since you are using base64 to obfuscate a string, you can just confuse it with something else, like rot13 (or your own simple letter replacement function). So urlencode(str_rot13($str)) for encoding and str_rot13(urldecode($str)) for decoding.

Or, just to have a shorter base64 encoded string, you could compress the string before base64 encodes it: base64_encode(gzencode($str, 9)) and gzdecode(base64_decode($str)) for decoding.

Or, if this is primarily a security issue (you don’t mind that people see the URL, you just want people to not crack it), you could pass these parameters using regular request variables, but with a hash added to prevent falsification. i.e:.

 function getHash($url, $width, $height) { $secret = 'abcdefghijklmnopqrstuvwxyz whatever you want etc.'; return sha1($url . $width . $height . $secret); } // So use this hash to to construct your URL querystring: $hash = getHash($url, $width, $height); $urlQuerystring = '?url='.urlencode($url).'&width='.(int) $width. '&height='.(int) $height.'&hash='.$hash; // Then in your code that processes the URL, check the hash first if ($hash != getHash($url, $width, $height)) // URL is invalid 

(Disable topic: people say that you should use POST instead of GET. If all of these URLs are displaying screenshots from your database for display (i.e. search), then GET is correct and correct. But if you call these URLs actually do things like go to another site, create and save a screenshot, and then POST. As their names indicate, GET is for searching, POST is for sending data. If you must use GET for an expensive operation, for example, by taking a screenshot, you can cum DOSing your site when Google index and so on, these URL-addresses.)

+5
source share

It looks like your goals are: 1. to visually hide the URL and 2. to generally encode the data for use in the URL.

First, we need to eclipse the URL. Since URLs use most of the Base64 dictionary, any encoding that creates the binary (which should then be Base64-ed) is likely to simply increase the size. It’s best to keep the dictionary in a URL-safe range with minimal escaping when using urlencode() . That is, you want this:

 /** * Rot35 for URLs. To avoid increasing size during urlencode(), commonly encoded * chars are mapped to more rarely used chars (end of the uppercase alpha). * * @param string $url * @return string */ function rotUrl($url) { return strtr($url, 'abcdefghijklmnopqrstuvwxyz0-:/?=&%#123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ', '123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0-:/?=&%#'); } 

Now, to save bytes, we can encode the URL scheme into one char (say, h for HTTP, h for HTTPS) and convert the sizes to base 32. Finishing this:

 function obscure($width, $height, $url) { $dimensions = base_convert($width, 10, 32) . "." . base_convert($height, 10, 32) . "."; preg_match('@^(https?)://(.+)@', $url, $m); return $dimensions . (($m[1] === 'http') ? 'h' : 'H') . rotUrl($m[2]); } function unobscure($str) { /* exercise for the reader! */ } $url = 'https://en.wikipedia.org/w/index.php?title=Special%3ASearch&search=Base64'; $obs = obscure(550, 300, $url); // h6.9c.H5E.N9B9G5491.FI7UNU9E45O.G8GVK9KC5W-G5391CYcj-51I38XJ51I38Wk1J5fd 

Since we avoided characters that do not contain URLs, if this is placed in querystring (with urlencode ), it does not grow much (in this case, not at all).

In addition, you may want to sign this line so that people who know the encoding still cannot specify their parameters through the URL. For this you must use HMAC , and Base64URL - hash encoding. You can also just save the hash substring (~ 6 bits per character) to save space. sign() (below) adds an 8-digit MAC (48 bit hash at 6 bits / char):

 function sign($key, $data) { return $data . _hmac($key, $data, 8); } function verify($key, $signed) { $mac = substr($signed, -8); $data = substr($signed, 0, -8); return $mac === _hmac($key, $data, 8) ? $data : false; } function _hmac($key, $data, $macLength) { $mac = substr(base64_encode(hash_hmac('sha256', $data, $key, true)), 0, $macLength); return strtr($mac, '+/', '-_'); // for URL } $key = "Hello World!"; $signed = sign($key, $obs); // appends MAC: "w-jjw2Wm" $obs = verify($key, $signed); // strips MAC and returns valid data, or FALSE 

Update: Better RotURL function .

+2
source share

Just not base64_encode($whole_file) . Send the contents to pieces and encode the pieces. In addition, if you need to know how to increase your piece after calling base64_encode() , it will be more than double (but less than 2.1*strlen($chunk) )

+1
source share

You can still use POST for what you are describing, if I understood correctly, maybe I haven't.

I assume you are doing something like this:

 <a href="scripturl?w=11&h=100&url=really-long-secret-base64"> <img src="imgurl"> </a> 

instead, do something like this:

 <form method="POST" action="scripturl"> <input type="hidden" name="width" value="100"> <input type="hidden" name="height" value="100"> <input type="hidden" name="url" value="secret-url-string-here"> <input type="image" src="imgurl" name="submit"> </form> 
+1
source share

Is a script that generates URLs running on another server from a script that interprets them? If they are on the same server, the obvious approach would be to save the destination URL, width and height in the database and simply pass in an arbitrarily generated record identifier to the query string.

0
source share

All Articles