1
pubby 2015-11-12 11:07:29 +08:00
偶尔我用 /user/{uid}-{md5(uid+key)} 的形式防止遍历
|
3
wy315700 2015-11-12 11:08:43 +08:00
short_uuid
|
4
undeflife 2015-11-12 11:12:31 +08:00
不需要算法 id 随便什么规律都好 没规律也行
fail2ban 解析 access.log 多次符合规则的 404 ban 掉就行了 |
7
est OP |
8
xujif 2015-11-12 11:18:43 +08:00
弄几个魔术 id ,访问就 ban
|
9
cyr1l 2015-11-12 11:18:59 +08:00 1
比如判断是否是质数或者是否能被某个质数(比如 17 ) 整除?
|
10
akira 2015-11-12 11:19:18 +08:00
自增的 id 只对内部使用,对外是一个 uuid 或者和 id 无表面关系的字符串
|
11
lanlanlan 2015-11-12 11:21:13 +08:00
只要爬虫 IP 资源够 都是浮云嘛→_→
|
12
est OP @wy315700 而且如果 mysql 里用的话,还有可能冲突。。虽然很小概率。但是为了防止冲突还得加个唯一索引。这是要让人纠结死。。。而如果自增的话,直接根据上一个 id ,按照某一个算法,跳过一些 id ,就可以得到下一个 id 了。。。现在就是在想有没有这个比较好的算法。不容易猜出来,服务器计算和判断速度也比较快的。
|
13
est OP @lanlanlan 如果加上运营商判断, ip 没那么好找哦。比如只允许 ADSL 的 IP 段访问,代理 ip 绝大多数是机房 ip 段。很容易判断出来。我见过很多国外论坛都只允许 comcast verizon at&t 之类的民用宽带 ip 访问。我换了 n 个代理,但是因为出口都是机房,都被判断出来了。
|
14
est OP @xujif 我也是这样想的,但是从代码维护的角度来说,每人工增加一个 magic id 就要改代码,部署流程,或者改 config ,感觉略蛋痛。
|
17
Elethom 2015-11-12 11:26:42 +08:00 via iPhone
那自增就沒有意義了。還不如 hash 。
|
18
zhujinliang 2015-11-12 11:29:23 +08:00
之前有个类似的需求,当时的做法很 2b
把 id 以十进制表示,然后每位随机做一个的对照表,然后再拼起来 |
19
RitianZhao1988 2015-11-12 11:35:11 +08:00
内部一张表,外部一张表
外部增加时有几率增加 rand 个魔术 id ,然后在内部表里再写一份没有 magic id 的怎么样? |
20
undeflife 2015-11-12 11:42:36 +08:00
@est 你的"间隙" id 同样不能解决这个问题
如果 /users/xxxx 这样一个 url 并不存在分享的需求的话 无所谓友好不友好. 如果存在分享的需求的话 /users/username 这样不是更好吗 所以我认为完全可以从设计上弱化 uid 在用户这的存在 |
22
18000rpm 2015-11-12 11:53:37 +08:00
跟着思路走只能想到多挖几个坑 233
一个一位数的坑 两个两位数的坑 三个三位数的坑 能整除的都不能踩,不知道这个在没遍历前还好不好猜规律 |
23
lwbjing 2015-11-12 11:58:34 +08:00
mongodb _id
|
24
oott123 2015-11-12 12:00:57 +08:00 1
|
25
lincanbin 2015-11-12 12:06:11 +08:00
用 GUID+截断的时间戳作为主键,可以获得更高的插入效率,同时也可以一定程度防止爬虫。
|
26
muzuiget 2015-11-12 12:11:43 +08:00
自增 id 只在服务器器使用,对外就 hash 不就行了么, hash 同表也是唯一,允许所以?不让客户端通过 id 访问到资源。
|
27
imn1 2015-11-12 12:15:54 +08:00
虽然会增加我将来爬东西的难度,但还是要说一句话:
外显有序 id 是低智商 说个故事: 上世纪末,要抓日本某站点一批数据,当时只知道 max(id)>=17000 ,步长 1 自增 还不会写爬虫,于是开网络蚂蚁批量,直接下 大约抓了 5000 条左右,那站点停了几小时,然后页面浏览器访问顶部出现了“巡回禁止”的横条,哈哈 然后发现大约下 1000 条左右后面就会全部 404 老子 proxy 多,当年还没有 qiang 的概念, ssl proxy 都是稀有物,但 http proxy 还是不少,因为原生网路就不畅,非人为原因…… 然后就每 800 条换一个 proxy ,爬完(换了多个确认是真的没有数据而不是 404 ),总数 26000+条 这是当年不为爬 qiang 而使用梯子的典型例子 凭这 2w 条信息,虽然没有全部发布,并且是重新组织和翻译,在小圈子也有点名气 但也属盗版了,后来还是怕担责(即使日本追究不到我这来),撤了,自此之后虽然爬数据,但再也没批量公开发布了 反正从那时开始我就禁止后台程序员使用外显有序 id 了 @akira 说的是对的,其实不要想什么算法,因为读取的次数比写入多得多,在写入时产生一个唯一用于外显的 uid 则可,读取时用算法判定会严重增加机器负担 |
28
est OP |
29
est OP @wy315700
仔细看了下 The UUID_SHORT() return value is constructed this way: (server_id & 255) << 56 + (server_startup_time_in_seconds << 24) + incremented_variable++; 感觉也算一个不明显的自增 id 的思路吧。。。。 |
30
est OP @oott123 好东西。不过 ruby 有个更好的,基于 Perfect hash function 的 https://github.com/namick/obfuscate_id
|
32
livelazily 2015-11-12 12:42:25 +08:00
跳过所有质数
|
34
lerry 2015-11-12 12:52:25 +08:00
mongoDB 的 ObjectId
https://docs.mongodb.org/manual/reference/object-id/ |
35
twor2 2015-11-12 13:04:53 +08:00
uuid 只是视觉上的长,其实还好,网址都是点进去的,就算是 1234 ,也不会有人敲进去吧
|
36
liboyue 2015-11-12 13:05:51 +08:00
用一个表呗。把顺序的内部 ID 映射到随机 ID 上,多一次查表的操作
|
37
XiaoxiaoPu 2015-11-12 13:10:58 +08:00
把自增 ID 用 RSA 加密(或其他加密算法),加密后的结果给用户,用户传过来的 ID 解密,不知道是否可行
|
38
est OP @livelazily 2333 好办法!
|
40
millken 2015-11-12 13:36:02 +08:00 2
php 版 obfuscate_id
https://github.com/jenssegers/optimus |
41
est OP @ts 网址我都背熟了。 newsmth.net/mainpage.html 纯手打。
|
42
wingoo 2015-11-12 13:41:51 +08:00
base62
映射规则自己指定下 |
43
hooopo 2015-11-12 13:45:21 +08:00
内部设置一个私有函数产生黑洞 ID...
|
44
ooh 2015-11-12 13:47:50 +08:00
没有任何实际意义
|
45
windows98 2015-11-12 13:58:15 +08:00 1
看帖子的同时,瞟了一眼这个帖子的 url...
|
46
ibireme 2015-11-12 14:02:16 +08:00
用 MongoDB 的 ID 生成办法就不错啊~
|
47
est OP |
48
dong3580 2015-11-12 14:40:21 +08:00
|
50
Felldeadbird 2015-11-12 15:23:40 +08:00
如果是闭源的话,直接 参数+自增 ID+参数。 混淆进去就行了。
如: order_id =1 ;那么访问的 URL 地址为: /xxx.io?order=6544678198786782 拆分为三部分: 6544678 、 1 、 98786782 。 |
51
fork3rt 2015-11-12 15:58:22 +08:00
好无聊的方法。。。
|
53
xierch 2015-11-12 16:10:06 +08:00
next_id = hmac(last_id, key) % MAX_GAP + 1
|
54
xierch 2015-11-12 16:10:46 +08:00
哦,不是 =,是 +=
|
55
xierch 2015-11-12 16:11:44 +08:00
next_id = last_id + 1 + hmac(last_id, key) % MAX_GAP
|
56
est OP @zdhxiong 你再想想呢?比如我 margin-left: -10000px 一个 div 里弄一个陷阱链接,你访问就直接给你永久返回垃圾数据。镜像下来然后呢?
|
57
huobazi 2015-11-12 16:27:56 +08:00
snowflake
|
58
est OP |
59
iambic 2015-11-12 16:32:44 +08:00
感觉是不是就是一个 integer hashing 问题啊
这个链接 https://gist.github.com/badboy/6267743 应该有用。另外 redis 源码里, dict.c 用的 Thomas Wang 的 hashing function 应该也可以参考下 |
60
clino 2015-11-12 16:34:11 +08:00
取当前时间
|
66
jsq2627 2015-11-12 17:20:24 +08:00
UUID/GUID 当然是最好的。只不过长的比较丑,对用户不友好。不过还是可以避免,我们最近在做的一个系统,用户注册后就必须得输入一个五位代码做 URL 定位部分。
|
67
FrankFang128 2015-11-12 17:32:09 +08:00
ban 有什么用,很快就发现你的规律了。
|
68
haython 2015-11-12 17:35:41 +08:00
用进制转换啊, 10 进制转换成 36 进制, 10 数字加 26 个字母,把顺序打乱
|
69
xierch 2015-11-12 18:23:39 +08:00
不如 ID 还是按顺序自增,但是提供给用户的时候,在末尾加一位数用作校验?
效果应该类似于,每两个 ID 之间平均间隔 10 个黑洞 校验值可以用任意算法加密 ID ,然后 mod 10 得到.. 推广一下,可以用 id * N + (encrypt(id) % N) 得到带校验码的 id_v 服务器收到 id_v 以后,用 id_v / N 得到原 ID , 然后用 id_v % N == encrypt(id, key) % N 判断是否正确。 ( N >= 2 ,越大掺的洞越多( |
70
dallaslu 2015-11-12 20:06:53 +08:00
1. 使用自增 ID ,记为 A ;
2. 生成 UUID ,去掉前面的 0 ,再取前 X 位按 16 进制转为 10 进制的值,记为 B ; 3. 计算 X 位 16 进制数字的 10 进制值的数字个数(如 4 位 16 进制数字 FFFF 10 进制值为 65535 ,数字个数为 5 ),记为 C ; 4. 在 B 的前面补 0 ,以使长度等于 C ,将其记为 D ; 5. 把 A 和 D 拼接起来,用做外显 ID 。 比如设 X 为 4 , A 为 235554 , UUID 为 3FE4C8B33C ...,则: B = 0x3FE4 = 16356 ; C = 5 ; D = 16356 ; ID = 23555416356 遇到 404 就可以判为爬虫了。话又说回来,自增 ID 后面拼上定长的随机数不就好了么! |
71
dallaslu 2015-11-12 20:10:40 +08:00
当然了,如果还有校验的需求,可以用 md5(id+salt) 来代替 UUID ,参与 12345 运算……
|
73
ctftemp 2015-11-12 20:17:51 +08:00 via Android
id 加盐 hash 一下,拿这个 hash 值作为判断依据就比较难预测了吧?
|
76
Hipponensis 2015-11-12 20:59:42 +08:00
LS 许多思路学习了,但总觉得防遍历有点舍本逐末,不如 ID 还是按顺序自增,然后下陷阱,某些 id 对应的页面用户无法访问,让爬虫进去,然后封禁对应 ip 。以上爬虫新手瞎想的。
|
77
varrily 2015-11-12 23:47:16 +08:00
我在用 base58(uuid) 长度 22 位左右。比直接 uuid 短不少。
|
78
msg7086 2015-11-12 23:48:51 +08:00
|
80
holyghost 2015-11-13 09:26:47 +08:00 via iPhone 1
有开源的 hashids 不用。。。
|
82
xiaogui 2015-11-13 12:24:37 +08:00
不过非连续 ID 并不能完全阻止被爬虫。
|
85
un 2015-11-20 10:31:59 +08:00
|