Có vẻ như mục tiêu của bạn là 1. để làm mờ một URL một cách trực quan và 2. để thường mã hóa dữ liệu gọn gàng để sử dụng trong URL.
Trước tiên, chúng tôi cần che khuất URL. Vì URL sử dụng nhiều từ điển Base64, bất kỳ mã hóa nào tạo ra nhị phân (mà sau đó phải là Base64-ed) sẽ có khả năng tăng kích thước. Tốt nhất là giữ từ điển trong phạm vi an toàn của URL với nhu cầu tối thiểu để thoát khi áp dụng urlencode()
. I E. bạn muốn điều này:
/**
* 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-:/?=&%#');
}
Bây giờ, để tiết kiệm byte, chúng ta có thể mã hóa các giản đồ URL vào một char (nói, h
cho HTTP, H
cho HTTPS), và chuyển đổi kích thước thành cơ sở 32. Bao bì này lên:
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
Vì chúng ta tránh chars phi URL-an toàn, nếu điều này được đặt trong một chuỗi truy vấn (với urlencode
), nó không phát triển nhiều (trong trường hợp này không phải ở tất cả).
Ngoài ra, bạn có thể muốn ký chuỗi này để những người biết mã hóa vẫn không thể chỉ định tham số riêng của họ thông qua URL. Đối với điều này, bạn sẽ sử dụng HMAC và mã hóa Base64URL băm. Bạn cũng có thể chỉ giữ một chuỗi con của hàm băm (~ 6 bit cho mỗi ký tự) để tiết kiệm không gian.sign()
(dưới đây) cho biết thêm 8 nhân vật MAC (48 bit của băm lúc 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
Cập nhật: a tốt hơn RotURL function.
Có lý do cụ thể nào để không sử dụng POST hoặc Phiên thay thế không? Chúng phù hợp hơn nhiều để truyền khối dữ liệu có kích thước hợp lý giữa các trang –
Không thực sự có thể sử dụng bài đăng (tôi nghĩ là anyway). Nó đang được sử dụng để có được một hình ảnh và kích thước của nó (mà là trong một mảng serialized bên trong chuỗi được mã hóa). Nó phải hoạt động với một thẻ tiêu chuẩn html . – Sk446
Tôi đang bối rối. Bạn đang gửi hình ảnh từ máy chủ hoặc từ trình duyệt? –