我正在考虑写一个网页,为客户提供反馈表.
我希望客户能够使用任何特定订单的唯一URL访问此表单; 一个简单的例子是http://www.example.com/feedback/012345格式.
旁注:我已经熟悉URL重写.在给定语言或给定服务器上创建/重定向URL超出了本问题的范围
客户必须进行身份验证(或者,就此而言,甚至拥有帐户)才能访问反馈表单,这是不可接受的.但是,出于对统计正确性的关注,我对example.com/feedback/[order_id]上面的明显解决方案不满意.这允许任何人更改URL中的ID并访问另一个订单的反馈.
另一方面,我希望能够从打印输出(例如收据)输入这些URL,因此在许多"重置密码"链接上提供长哈希不是有效选项.
基于此,我有以下标准:
我的想法是我应该在URL中放入两个数据.客户记录中有很多人类可读的数据可以帮助解决这个问题,例如客户ID,订单的联系电话号码,姓氏......虽然这样就无法更改一两个数字,但我没有看到它显着改善了给无聊攻击者的给定URL的"可猜测性".
以/ feedback/[surname]/[id]的简单示例为例,您可以通过简单的字典攻击页面来接收一组有效的URL:
for x in range(00000,99999):
for name in ["jones","smith", ....]:
url = "http://www.example.com/feedback/"+name+"/"+x
if exists(url):
print(url)
Run Code Online (Sandbox Code Playgroud)
我考虑的下一件事,就像tinyurl这样的服务,是散列ID号并以/ feedback/[hash]/[id]的形式提供一个URL
我已经做了一些研究并且实际上了解到URL缩短服务可能使用自动增量ID记录而不是实际的数学哈希.这种方法可能没用
如果使用实际的散列函数,则重要的是散列不明显地从ID号导出.提供像/ feedback/trpxq/53192这样的URL是没用的,因为在看到其中的一个或两个后,您可以轻松地拉出以前的记录:/ feedback/trpxp/53191
我当时正在考虑,如果散列包含一个salt,那么即使知道使用了什么散列函数,也不可能散列任何旧的有效订单ID并调出有效的URL.
所以,最后,这是实际的问题:
什么函数最好用于创建基于7-10位整数ID和任意盐的哈希的短,非显而易见,相对独特的字母数字表示?
这不是URL缩短问题本身,所以如果散列部分与ID部分的长度相同,我会感到满意:减少到10个字母数字字符是可以接受的.
此外,每次访问URL时都不一定需要计算哈希值.无论是在创建订单记录时,还是在首次访问该订单ID的页面时,都可以对其进行计算.这意味着散列函数不一定非常快.
虽然有可能基本上为查找目的创建哈希表,但是这个问题与哈希表没有相同的限制:查找是基于已经唯一的值完成的,因此冲突解决并不是绝对必要的,只要它足够难以找到具有给定哈希的相同哈希的另一记录.
我们现在已经完全超出了确保反馈形式需要做的实际领域 - 这些数据实际上并不重要 - 但是幽默我,这是一个有趣的问题,我想知道是否有一个最好的安全性和可读性的解决方案.
我一直在使用python 3.3中的memoization和recursion
忽略python是这样做的错误语言的事实,我发现在使用 functools.lru_cache memoize和不使用之间我得到了不一致的结果 functools.lru_cache
我没有改变递归限制 - 它保持默认值,对我来说是1000.
为了测试这个问题,我写了一个简单的递归函数来对从1到i的数字求和
#!/usr/bin/python
def sumtil(i):
"""Recursive function to sum all numbers from 1 through i"""
# Base case, the sum of all numbers from 1 through 1 is 1...
if i == 1:
return 1
else:
return i+sumtil(i-1)
# This will not throw an exception
sumtil(998)
# This will throw an exception
sumtil(999)
Run Code Online (Sandbox Code Playgroud)
正常运行此功能,我可以sumtil(998)舒适地运行而不会达到递归限制.sumtil(999)或以上将抛出异常.
但是,如果我尝试使用此函数进行装饰,则在运行时会提前3次@functools.lru_cache()抛出递归限制异常sumtil(333)
#!/usr/bin/python
import functools
@functools.lru_cache(maxsize=128)
def sumtil(i): …Run Code Online (Sandbox Code Playgroud)