2009-12-10 41 views
6

Tôi có một tập lệnh để chuyển đổi thành cơ số 62 (A-Za-z0-9) nhưng làm cách nào để lấy số ra khỏi MD5?Chuyển đổi MD5 thành base62 cho URL

Tôi đã đọc ở nhiều nơi vì số từ MD5 lớn hơn php có thể xử lý dưới dạng số nguyên, nó sẽ không chính xác ... Vì tôi muốn một URL ngắn và không có kế hoạch sử dụng toàn bộ băm, có thể chỉ 8 ký tự của nó ....

Vì vậy, câu hỏi của tôi là làm thế nào để có được một phần của số lượng một băm MD5?

Bạn cũng nên sử dụng một phần của băm MD5?

+0

hàm băm md5 không phải là số, vì vậy bạn có ý nghĩa gì bởi "một phần của số"? –

+5

md5 là một số được trình bày trong mã hóa base36 mà tôi nghĩ ... – Mark

+1

Bạn là một nửa phải, băm md5 là một số hex được trình bày trong cơ số 16 (a-f0-9). –

Trả lời

6

Tôi sẽ đề nghị một điều khác nhau ở đây .. Vì bạn chỉ quan tâm trong việc sử dụng một đoạn thập phân của các hash md5 tại sao bạn không sử dụng bất kỳ băm số ngắn khác như CRC32 hoặc Adler? Dưới đây là ví dụ:

$hash = sprintf('%u', crc32('your string here')); 

Điều này sẽ tạo ra băm 8 chữ số của chuỗi của bạn.

EDIT: Tôi nghĩ rằng tôi đã hiểu lầm bạn, here are some functions that provide conversions to and from bases up to 62.

CHỈNH SỬA (Một lần nữa): Để làm việc với số lượng dài tùy ý, bạn phải sử dụng bc_math hoặc phần mở rộng GMP, here is a function that uses the bc_math extension and can also convert from base 2 up to base 62. Bạn nên sử dụng nó như thế này:

echo bc_base_convert(md5('your url here'), 16, 62); // public base 62 hash 

và nghịch đảo:

echo bc_base_convert('base 62 encoded value here', 62, 16); // private md5 hash 

Hy vọng nó giúp. =)

+0

là nó có thể làm việc ra những gì đã đi vào băm? Chỉ là tôi đang nghĩ nếu tôi chỉ cho thấy một phần của một băm nó phải làm cho nó khó khăn hơn để tập luyện như thế nào nó được tạo ra ... phải không? – Mark

+0

Phải, nhưng sau đó nó sẽ không phải là một băm theo nghĩa thực sự của từ, cũng va chạm là nhiều hơn nữa có thể xảy ra. –

1

Bạn có thể làm điều này như thế này:. (Không phải tất cả các bước được trong php, nó được một thời gian dài mà tôi đã sử dụng nó)

  • Tạo một hash md5 của kịch bản như thế này :

    $ hash = md5 (script, raw_output = true);

  • Chuyển đổi con số đó để căn 62.

    Xem các câu hỏi về base conversion of arbitrary sized numbers in PHP

  • Truncate chuỗi với độ dài bạn muốn.

Không có rủi ro khi chỉ sử dụng một vài bit của md5. Tất cả những thay đổi đó là nguy cơ va chạm.

+0

Liên kết tốt đẹp, cảm ơn. –

0

Bạn có thể sử dụng một cơ sở sửa đổi hơi 64 với -_ thay vì +/:

function base64_url_encode($str) { 
    return strtr(base64_encode($str), array('+'=>'-', '/'=>'_')); 
} 
function base64_url_decode($str) { 
    return base64_decode(strtr($str, array('-'=>'+', '_'=>'/'))); 
} 

Ngoài ra bạn có thể loại bỏ các dấu đệm = ký tự.

Và để có được giá trị MD5 liệu (chuỗi nhị phân), thiết lập tham số thứ hai (tên $raw_output trong cuốn hướng dẫn) để đúng:

$raw_md5 = md5($str, true); 
+0

kiểm tra http://stackoverflow.com/questions/352434/base-conversion-of-arbitrary-sized-numbers-php/1743486#1743486 –

+0

Điều gì sai? Tại sao bỏ phiếu xuống? – Gumbo

3

Nếu có thể, tôi muốn khuyên không sử dụng băm cho các URL của bạn. Cuối cùng, bạn sẽ gặp phải xung đột ... đặc biệt nếu bạn cắt xén băm. Nếu bạn tiếp tục và triển khai một hệ thống dựa trên id trong đó mỗi mục có một ID duy nhất, sẽ có ít đau đầu hơn rất nhiều. Mục đầu tiên sẽ là 1, mục thứ hai sẽ là 2, v.v ... nếu bạn đang sử dụng MySQL, chỉ cần ném vào cột tự động.

Để thực hiện một id ngắn:

//the basic example 
$sid = base_convert($id, 10, 36); 

//if you're going to be needing 64 bit numbers converted 
//on a 32 bit machine, use this instead 
$sid = gmp_strval(gmp_init($id, 10), 36); 

Để thực hiện một id ngắn trở lại vào cơ số 10 id:

//the basic example 
$id = base_convert($id, 36, 10); 

//if you're going to be needing 64 bit numbers 
//on a 32 bit machine, use this instead 
$id = gmp_strval(gmp_init($shortid, 36)); 

Hope this helps!

Nếu bạn đang thực sự muốn cơ sở 62 (mà không thể được thực hiện với gmp hoặc base_convert), kiểm tra này: http://snipplr.com/view/22246/base62-encode--decode/

+0

GMP, đẹp nhất! =) –

+0

Xin lỗi có lẽ tôi đã không làm cho bản thân mình rõ ràng đủ, md5 không hoạt động như một id ... cũng giống như một cách để ngăn chặn người dùng đoán url tiếp theo ... vì vậy url là id = 1 & md5 = dsf213sfe. Cảm ơn bạn anyway – Mark

+0

Đủ công bằng! Lỗi của tôi. Đừng bận tâm tôi :) – brianreavis

0

Bạn có thể làm một cái gì đó như thế này,

$hash = md5("The data to be hashed", true); 
$ints = unpack("L*num", $hash); 

$hash_str = base62($ints['num1']) . base62($ints['num2']) . base62($ints['num3']) . base62($ints['num4']) 
0

Có thực sự là một triển khai Java mà bạn có thể trích xuất. Đó là một giải pháp CMS nguồn mở có tên là Pulse.

Nhìn ở đây để biết mã số toBase62()fromBase62().

http://pulse.torweg.org/javadoc/src-html/org/torweg/pulse/util/StringUtils.java.html

Các phụ thuộc duy nhất ở StringUtils là vòng đời-lớp mà cung cấp một cách để có được một băm ướp muối cho một chuỗi mà bạn thậm chí có thể bỏ qua tất cả cùng nhau hoặc chỉ cần sao chép các phương pháp trên để sao chép của bạn StringUtils. Voilá.

0

Kể từ PHP 5.3.2, GMP hỗ trợ cơ sở lên đến 62 (trước đây chỉ có 36), vì vậy đề xuất của brianreavis rất gần. Do đó, tôi cho rằng câu trả lời đơn giản nhất cho câu hỏi của bạn là:

function base62hash($source, $chars = 22) { 
    return substr(gmp_strval(gmp_init(md5($source), 16), 62), 0, $chars); 
} 

Chuyển đổi từ base-base xuống 62 rõ ràng là có lợi ích về không gian. Một băm MD5 128 bit bình thường là 32 ký tự trong hex, nhưng trong cơ sở 62 nó chỉ 22. Nếu bạn đang lưu trữ băm trong cơ sở dữ liệu, bạn có thể chuyển đổi chúng thành nhị phân thô và tiết kiệm nhiều không gian hơn (16 byte cho một MD5).

Kể từ khi kết quả băm chỉ là một biểu diễn chuỗi, bạn chỉ có thể sử dụng chất nền nếu bạn chỉ muốn một chút của nó (như chức năng không).

0

Bạn có thể thử base62x để có được một đại diện được mã hóa an toàn và tương thích.

Here is for more information about base62x hoặc đơn giản là -base62x trong -NatureDNS.

shell> ./base62x -n 16 -enc 16AF 
1Ql 
shell> ./base62x -n 16 -dec 1Ql 
16AF 

shell> ./base62x 
Usage: ./base62x [-v] [-n <2|8|10|16|32>] <-enc|dec> string 
Version: 0.60