Sembra che i tuoi obiettivi siano 1. a visivamente oscurare un URL e 2. in genere codificare i dati in modo compatto per l'utilizzo in un URL.
In primo luogo, dobbiamo oscurare l'URL. Poiché gli URL utilizzano gran parte del dizionario Base64, qualsiasi codifica che produca file binari (che quindi deve essere Base64-ed) probabilmente aumenterà le dimensioni. È preferibile mantenere il dizionario nell'intervallo sicuro da URL con il minimo bisogno di escape quando viene applicato urlencode()
. Cioè si desidera che questo:
/**
* 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-:/?=&%#');
}
Ora, per il salvataggio di byte, si può codificare lo schema URL in un char (diciamo, h
per HTTP, HTTPS per H
), e convertire le dimensioni nella base 32. Wrapping questo in su:
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
Dal momento che abbiamo evitato caratteri non sicuro per le URL, se questo viene messo in una querystring (con urlencode
), non cresce molto (in questo caso non a tutti).
Inoltre, è possibile che si desideri firmare questa stringa in modo che le persone che conoscono la codifica non possano ancora specificare i propri parametri tramite l'URL. Per questo useresti HMAC e Base64URL-encoding l'hash. Puoi anche solo mantenere una sottostringa dell'hash (~ 6 bit per carattere) per risparmiare spazio.sign()
(sotto) aggiunge un carattere 8 MAC (48 bit dell'hash a 6 bit/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
Modifica: una migliore RotURL function.
C'è qualche motivo particolare per non utilizzare invece il POST o le sessioni? Sono molto più adatti per il passaggio di blocchi di dati di dimensioni corrette tra le pagine –
Non è davvero possibile utilizzare post (penso comunque). Viene utilizzato per ottenere un'immagine e le sue dimensioni (che si trovano in una matrice serializzata all'interno della stringa codificata). Deve funzionare con un tag html standard . – Sk446
Sono confuso. Stai inviando l'immagine dal server o dal browser? –