可以从我正在处理的网页访问的数据库资源具有唯一的ID号,并且设置了auto_increment。所以url必须看起来像some.web.page.com/resource/id-number。
用户很容易注意到他可以在最后增加或减少数量以获得他喜欢的任何东西,而在这种情况下安全性不是很大的关注,我真的想防止这种行为
我试图找到一些可以将数字转换为随机字符串的函数,但是我失败了(在google.com上真的不知道要放在该字段中的内容;))。我也有自己的想法,但我更喜欢使用已经在某个地方运作良好的方法。该函数需要是对称的,因此我可以轻松生成字符串,并从该字符串中获取数字。有什么建议吗?
答案 0 :(得分:1)
Ray Morgan给出了PHP中的算法和实现。该算法有一些很好的属性,即:
作者本身解释了以下基本步骤
对于像我这样对PHP不熟悉的人来说,算法的Common Lisp端口看起来像是:
#-(and) (ql:quickload "ironclad")
#-(and) (ql:quickload "trivial-utf-8")
(defpackage "HASHID"
(:use "COMMON-LISP" "IRONCLAD" "TRIVIAL-UTF-8")
(:shadowing-import-from "COMMON-LISP" "NULL"))
(in-package "HASHID")
(defparameter +secret+ "Secret Password")
(defun sha1-hex-digest (string &optional (secret +secret+))
(let ((digest (make-digest :sha1)))
(update-digest digest (string-to-utf-8-bytes string))
(update-digest digest (string-to-utf-8-bytes secret))
(let* ((result (produce-digest digest))
(length (length result))
(char-length (* length 2))
(buffer (make-array char-length :element-type 'character))
(digits "0123456789ABCDEF"))
(loop
:with wp := 0
:for byte :across result
:do (setf (char buffer (prog1 wp (incf wp))) (char digits (ash byte -4)))
(setf (char buffer (prog1 wp (incf wp))) (char digits (logand byte 15)))
:finally (return buffer)))))
(defun obfuscate-id (identifier)
(let* ((segment-1 (subseq (sha1-hex-digest (format nil "~D" identifier)) 0 16))
(segment-2 (subseq (sha1-hex-digest (concatenate 'string segment-1)) 0 8))
(decimal (parse-integer segment-2 :radix 16))
(buried-id (if (< identifier decimal) (- decimal identifier) (+ decimal identifier)))
(new-segment-2 (format nil "~8,'0X" buried-id))
(segment-3 (subseq (sha1-hex-digest (concatenate 'string segment-1 new-segment-2)) 0 8)))
(concatenate 'string segment-1 new-segment-2 segment-3)))
(defun deobfuscate-id (string)
(let* ((segment-1 (subseq string 0 16))
(segment-2 (subseq string 16 24))
(segment-3 (subseq string 24))
(expected-2 (subseq (sha1-hex-digest segment-1) 0 8))
(expected-3 (subseq (sha1-hex-digest (concatenate 'string segment-1 segment-2)) 0 8)))
(and (string-equal segment-3 expected-3)
(let* ((v1 (parse-integer segment-2 :radix 16))
(v2 (parse-integer expected-2 :radix 16)))
(abs (- v1 v2))))))
请注意,原始实现从模糊ID生成了base-64编码的字符串,并将其用作实际值。我在这里省略了这一步,但添加起来应该很简单,尤其是your programming language of choice comes with base-64 support。