mydomain.com/show/?id=sf32JFSVANMfaskjfh
通常我只生成一个长度为25个字符的随机字符串并以这种方式访问我的帖子。但就今天而言,短网址是必要的。
如果我想要3个字母的ID ...我不能只生成随机字符。它会在某个时候发生冲突。
我该怎么办?
答案 0 :(得分:4)
<强> PHP:强>
运行:
rand_uniqid(9007199254740989);
将返回'PpQXn7COf'和:
rand_uniqid('PpQXn7COf',true);
将返回'9007199254740989'
如果你想让rand_uniqid长度至少为6个字母,请使用$ pad_up = 6参数
您可以通过在函数体顶部的$ index var中添加字符来支持更多字符(使得生成的rand_uniqid更小)。
<?php
function rand_uniqid($in, $to_num = false, $pad_up = false, $passKey = null)
{
$index = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
if ($passKey !== null) {
// Although this function's purpose is to just make the
// ID short - and not so much secure,
// you can optionally supply a password to make it harder
// to calculate the corresponding numeric ID
for ($n = 0; $n<strlen($index); $n++) {
$i[] = substr( $index,$n ,1);
}
$passhash = hash('sha256',$passKey);
$passhash = (strlen($passhash) < strlen($index))
? hash('sha512',$passKey)
: $passhash;
for ($n=0; $n < strlen($index); $n++) {
$p[] = substr($passhash, $n ,1);
}
array_multisort($p, SORT_DESC, $i);
$index = implode($i);
}
$base = strlen($index);
if ($to_num) {
// Digital number <<-- alphabet letter code
$in = strrev($in);
$out = 0;
$len = strlen($in) - 1;
for ($t = 0; $t <= $len; $t++) {
$bcpow = bcpow($base, $len - $t);
$out = $out + strpos($index, substr($in, $t, 1)) * $bcpow;
}
if (is_numeric($pad_up)) {
$pad_up--;
if ($pad_up > 0) {
$out -= pow($base, $pad_up);
}
}
$out = sprintf('%F', $out);
$out = substr($out, 0, strpos($out, '.'));
} else {
// Digital number -->> alphabet letter code
if (is_numeric($pad_up)) {
$pad_up--;
if ($pad_up > 0) {
$in += pow($base, $pad_up);
}
}
$out = "";
for ($t = floor(log($in, $base)); $t >= 0; $t--) {
$bcp = bcpow($base, $t);
$a = floor($in / $bcp) % $base;
$out = $out . substr($index, $a, 1);
$in = $in - ($a * $bcp);
}
$out = strrev($out); // reverse
}
return $out;
}
echo rand_uniqid(1);
?>
<强>的PostgreSQL:强>
<?php
CREATE OR REPLACE FUNCTION string_to_bits(input_text TEXT)
RETURNS TEXT AS $$
DECLARE
output_text TEXT;
i INTEGER;
BEGIN
output_text := '';
FOR i IN 1..char_length(input_text) LOOP
output_text := output_text || ascii(substring(input_text FROM i FOR 1))::bit(8);
END LOOP;
return output_text;
END;
$$ LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION id_to_sid(id INTEGER)
RETURNS TEXT AS $$
DECLARE
output_text TEXT;
i INTEGER;
index TEXT[];
bits TEXT;
bit_array TEXT[];
input_text TEXT;
BEGIN
input_text := id::TEXT;
output_text := '';
index := string_to_array('0,d,A,3,E,z,W,m,D,S,Q,l,K,s,P,b,N,c,f,j,5,I,t,C,i,y,o,G,2,r,x,h,V,J,k,-,T,w,H,L,9,e,u,X,p,U,a,O,v,4,R,B,q,M,n,g,1,F,6,Y,_,8,7,Z', ',');
bits := string_to_bits(input_text);
IF length(bits) % 6 <> 0 THEN
bits := rpad(bits, length(bits) + 6 - (length(bits) % 6), '0');
END IF;
FOR i IN 1..((length(bits) / 6)) LOOP
IF i = 1 THEN
bit_array[i] := substring(bits FROM 1 FOR 6);
ELSE
bit_array[i] := substring(bits FROM 1 + (i - 1) * 6 FOR 6);
END IF;
output_text := output_text || index[bit_array[i]::bit(6)::integer + 1];
END LOOP;
return output_text;
END;
$$ LANGUAGE plpgsql;
?>
<强> JavaScript的:强>
<script>
/*jslint white: true, browser: true, onevar: true, undef: true, nomen: true, eqeqeq: true, newcap: true, immed: true */
/*global Crypto:true */
if (typeof Crypto === 'undefined') {
Crypto = {};
}
Crypto.random = (function () {
var index = [
'b', 'c', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'm',
'n', 'p', 'q', 'r', 't', 'v', 'w', 'x', 'y', 'z',
'_', '-', '0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'B', 'C', 'D', 'F', 'G', 'H', 'J', 'K',
'L', 'M', 'N', 'P', 'Q', 'R', 'T', 'V', 'W', 'X',
'Y', 'Z'
], base = index.length;
return {
encode: function (i) {
var out = [],
t = Math.floor(Math.log(i) / Math.log(base)),
bcp,
a;
while (t >= 0) {
bcp = Math.pow(base, t);
a = Math.floor(i / bcp) % base;
out[out.length] = index[a];
i -= a * bcp;
t -= 1;
}
return out.reverse().join('');
},
decode: function (i) {
var chars = i.split(''),
out = 0,
el;
while (typeof (el = chars.pop()) !== 'undefined') {
out += index.indexOf(el) * Math.pow(base, chars.length);
}
return out;
}
};
}());
</script>
示例:
<script>
alert(Crypto.random.encode(101010101));
alert(Crypto.random.decode('XMzNr'));
</script>
答案 1 :(得分:2)
为什么不使用自动增量数字,如5836?每次插入新行时,该列将递增1。例如,如果最新的行是5836,则下一行将是5837,依此类推。
只使用长度为15的INT类型列。或者,如果它不是由常规成员添加的行类型,请使用小型int或中型int类型。
答案 2 :(得分:1)
作为一般规则,较短的哈希值会导致更高的冲突率。较长的哈希值也会导致冲突,但这种冲突的可能性会降低。
如果您想要更短的哈希值,则应实施冲突解决策略。
答案 3 :(得分:1)
如果你的每个帖子都有一个id,并且它是数字的,你可以使用任意基数对它们进行编码。想想有点像十六进制,但数字更大..
查看leah culver的这个网址...
http://blog.leahculver.com/2008/06/tiny-urls-based-on-pk.html
了解更多想法。我过去曾经使用过它,效果很好。在leah的帖子中它是base 56,所以只需拿走你的主键(整数)并将它编码到你的新基础56中,你就可以了。
答案 4 :(得分:1)
短网址是必要的
真的?为什么?您是否打算让用户手动输入?
我认为,因为它们几乎肯定是来自其他地方的链接,所以URL的大小几乎无关紧要。
担心用于访问帖子的网址大小的用户正在浪费时间。无论如何,如果你愿意,可以将一个大整数编码到base64或类似的东西,但我个人认为这是浪费时间,因为“你可能会做的事情可能会带来更大的投资回报”。 / p>
在Twitter上评论你的评论,我只是像现在一样为实际帖子分配连续的25个字符(或者更短的,如果你想要的话),然后使用缩短的版本来减少你需要的URL。例如,该25个字符的ID的最后4个字符。
然后将该4个字符的ID映射到最新的等效的25个字符的ID(意味着有两个URL(短和长)可以到达该帖子)。这意味着你的消息将有效,直到你翻身,但仍然会给你大量的活动消息(在base64,64 4 或超过1600万条消息)。
完整尺寸的网址将能够直接发布(实际上,因为25个字符可以为您提供大约10条 45 消息)。
答案 5 :(得分:0)
NOID: Nice Opaque Identifier (Minter and Name Resolver)旨在为图书馆系统执行此操作
但它的基本设计是它创建一个id并检查它是否已被使用,如果没有那么它可以在后台生成使用并向用户分发id可以避免创建它们的开销
答案 6 :(得分:0)
我要说你必须看到外侧和内侧。您不能拥有“仅3”字母的唯一数字,或者至少只能在短时间内使用。所以你可以使用内部长的identfiers,我想到的就是使用UUIDS,然后你必须弄清楚如何使这样的UUIDS使用漂亮或可读的URL。例如,如果我们看一下类似的帖子 YYYY.mm.dd.nnn可能会这样做。我建议查看REST方法......
答案 7 :(得分:0)
AFAIK大多数语言都有自己的方法。例如在PHP中,您可以使用内置函数uniqid()。 但是,使用此方法,还必须将生成的uniqid保存在数据库中,以便可以在SQL中的“where”子句中使用它。据我所知,没有办法解密这些所谓的GUID,因此他们不会告诉你任何关于何时制作或任何东西的信息。
<?php
//For a basic unique id based on the current microtime:
$uniq_id = uniqid();
//If you want it to be even more uniq, you can play around with rand().
function rlyUniqId(){
$letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghyjklmnopqursuvwxyz1234567890";
$letter_count = strlen($letters);
$prefix_letter_count = rand(1,4);
for($i=1;$i<=$prefix_letter_count;$i++){
$letter_pos = rand(0,$letter_count)-1;
$prefix .= substr($letters,$letter_pos);
}
return uniqid($prefix);
}
$rly_uniq_id = rlyUniqId();
?>
前面提到的另一个建议是使用标准生成的自动增量id,然后在你的URL中对它进行base64编码,这样它看起来很花哨。这可以再次解码,这意味着您只需解码url中的id即可调用数据库中的id。另一方面,任何人都可以这样做,所以如果要隐藏实际的id,这种方式绝不是理想的。此外,如果您有时需要手动编码链接,有时这种方法有点烦人。 从好的方面来说,它提供了比前面提到的uniqid()更短的网址。
<?php
$data_from_db = array("id"=>14,"title"=>"Some data we got here, huh?");
$url_id = base64_encode($data_from_db["id"]);
echo '<a href="readmore.php?id='.$url_id.'>'.$data_from_db["title"].'</a>';
//when reading the link, simply do:
$original_id = base64_decode($url_id);
?>
我知道这有点晚了,但我希望有一天会帮助某个人:P GL HF!