Sk4*_*446 6 php base64 encoding get
我正在编写一个脚本,它基本上允许我在单个get请求的查询字符串中发送一个URL和两个整数维度.我正在使用base64对它进行编码,但它很长,而且我担心URL可能会变得太大.
有没有人知道另一种更短的方法呢?它在get请求中收到时需要可解码,所以md5/sha1是不可能的.
谢谢你的时间.
编辑:抱歉 - 我应该更好地解释一下:好的,在我们的网站上,我们会显示已发布以供审核的网站的屏幕截图.我们有自己的缩略图/截图服务器.我基本上将使图像标记包含一个编码字符串,该字符串存储用于截取屏幕截图的URL,以及要显示的图像的宽度/高度.然而,我不想在"原始文本"中让世界看到它.显然,base64可以由任何人决定,但我们不希望你的普通乔获取URL路径.真的我需要在一个GET请求中获取:url,width,height.
由于您只使用base64对字符串进行模糊处理,因此您可以使用其他内容对其进行模糊处理,例如rot13(或您自己的简单字母替换函数).所以,urlencode(str_rot13($str))编码和str_rot13(urldecode($str))解码.
或者,只需要一个较短的base64编码字符串,您可以在base64编码之前压缩字符串:base64_encode(gzencode($str, 9))并gzdecode(base64_decode($str))解码.
或者,如果这主要是一个安全问题(你不介意人们看到这个URL,你只是想让人们不去攻击它)你可以用普通的查询字符串变量传递这些参数,但是附加一个哈希以防止篡改.即:
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
Run Code Online (Sandbox Code Playgroud)
(偏离主题:人们说你应该使用POST而不是GET.如果所有这些URL都是从你的数据库中获取截图来显示(即搜索查找),那么GET是正确的.但如果调用这些URL实际上是执行一个动作,比如去另一个站点,制作和存储截图,那就是POST.正如他们的名字所示,GET用于检索; POST用于提交数据.如果你要使用GET进行昂贵的操作,比如截图,当谷歌等索引这些网址时,你最终可能会管理你自己的网站.)
听起来您的目标是 1. 在视觉上模糊 URL,2. 通常对数据进行紧凑编码以在 URL 中使用。
首先,我们需要隐藏 URL。由于 URL 使用大部分 Base64 字典,任何生成二进制的编码(然后必须进行 Base64 编码)可能只会增加大小。最好将字典保留在 URL 安全范围内,并在urlencode()应用时尽量减少转义的需要。即你想要这个:
/**
* 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-:/?=&%#');
}
Run Code Online (Sandbox Code Playgroud)
现在,为了节省字节,我们可以将 URL 模式编码为一个字符(例如,h对于 HTTP、H对于 HTTPS),并将维度转换为基数 32。总结一下:
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
Run Code Online (Sandbox Code Playgroud)
由于我们避免使用非 URL 安全字符,因此如果将其放入查询字符串(使用urlencode),它不会增长太多(在本例中根本不会增长)。
此外,您可能希望对该字符串进行签名,以便知道编码的人仍然无法通过 URL 指定自己的参数。为此,您可以使用HMAC并对哈希值进行 Base64URL 编码。您还可以只保留哈希的子字符串(每个字符约 6 位)以节省空间。sign()(如下)添加一个 8 字符 MAC(48 位散列,6 位/字符):
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
Run Code Online (Sandbox Code Playgroud)
更新:更好的RotURL 函数。