2009-03-05 38 views
138

Tôi có một câu hỏi đơn giản mà đã xảy ra khi tôi muốn để lưu trữ các kết quả của một băm SHA1 trong một cơ sở dữ liệu MySQL:giá trị băm Lưu trữ SHA1 trong MySQL

nên VARCHAR lĩnh vực được bao lâu mà tôi lưu trữ các kết quả của băm?

+8

Nếu bạn chỉ googled sha1 nhấp chuột im cảm thấy may mắn và bạn sẽ có trên wikipedia, nơi bạn có thể tìm thấy nó luôn luôn là 160 bit. –

Trả lời

283

Tôi sẽ sử dụng VARCHAR cho dữ liệu có độ dài thay đổi, nhưng không có dữ liệu độ dài cố định. Vì giá trị SHA-1 là luôn luôn dài 160 bit, VARCHAR sẽ chỉ lãng phí an additional byte for the length of the fixed-length field.

Và tôi cũng sẽ không lưu trữ giá trị SHA1 đang trở lại. Bởi vì nó chỉ sử dụng 4 bit cho mỗi ký tự và do đó sẽ cần 160/4 = 40 ký tự. Nhưng nếu bạn sử dụng 8 bit cho mỗi ký tự, bạn sẽ chỉ cần một trường dài 160/8 = 20 ký tự.

Vì vậy, tôi khuyên bạn nên sử dụng BINARY(20)UNHEX function để chuyển đổi giá trị SHA1 thành nhị phân.

Tôi đã so sánh các yêu cầu bộ nhớ cho BINARY(20)CHAR(40).

CREATE TABLE `binary` (
    `id` int unsigned auto_increment primary key, 
    `password` binary(20) not null 
); 
CREATE TABLE `char` (
    `id` int unsigned auto_increment primary key, 
    `password` char(40) not null 
); 

Với triệu hồ sơ binary(20) mất 44.56M, trong khi char(40) mất 64.57M. InnoDB động cơ.

+2

Trong PostgreSQL, điều này sẽ dịch sang sử dụng trường bytea, phải không? – mvexel

+9

@Gumbo: Bạn thưa bạn, tôi tin rằng, đã làm điều này trước đây! :) –

+0

Giải pháp là tuyệt vời, nhưng có một điểm khác để sử dụng char (40) với hexa sha1 - điều này được sử dụng rộng rãi hơn nhiều, và sẽ có ít vấn đề chuyển đổi hơn trong mã ứng dụng. –

36

Hàm băm SHA1 dài 40 ký tự!

+80

Trong mã hóa hex ... –

6

Kích thước đầu ra của sha1 là 160 bit. Đó là 160/8 == 20 ký tự (nếu bạn sử dụng ký tự 8 bit) hoặc 160/16 = 10 (nếu bạn sử dụng ký tự 16 bit).

+0

Giả sử các ký tự nhị phân 8 bit. 40 ký tự nếu được lưu dưới dạng hex. – Tyzoid

3

Vì vậy, độ dài giữa 10 ký tự 16 bit và 40 chữ số thập phân.

Trong mọi trường hợp, hãy quyết định định dạng bạn sẽ lưu trữ và đặt trường thành kích thước cố định dựa trên định dạng đó. Bằng cách đó bạn sẽ không có bất kỳ không gian lãng phí nào.

2

Bạn vẫn có thể muốn sử dụng VARCHAR trong trường hợp bạn không luôn lưu trữ băm cho người dùng (ví dụ: xác thực tài khoản/quên url đăng nhập). Khi người dùng đã xác thực/thay đổi thông tin đăng nhập của họ, họ sẽ không thể sử dụng băm và không nên có lý do. Bạn có thể tạo một bảng riêng biệt để lưu trữ các băm tạm thời -> các liên kết người dùng có thể bị xóa nhưng tôi không nghĩ rằng hầu hết mọi người đều bận tâm để làm điều này.

2

Nếu bạn cần chỉ mục trên cột sha1, tôi đề xuất CHAR (40) vì lý do hiệu suất. Trong trường hợp của tôi, cột sha1 là mã xác nhận email, do đó, trên trang đích truy vấn chỉ nhập bằng mã thông báo. Trong trường hợp này CHAR (40) với INDEX, theo ý kiến ​​của tôi, là lựa chọn tốt nhất :)

Nếu bạn muốn áp dụng phương pháp này, hãy nhớ để nguyên $ raw_output = false.

+1

Tại sao bạn không chỉ mục BINARY (20)? Nó sẽ không nhanh như vậy và một nửa có kích thước lớn không? – nickdnk

+0

Vâng điều này ~ 5 năm trước, nhưng tôi nghĩ rằng tôi đã đề cập đến một thực tế là bạn vẫn cần phải unhex mà thêm một số tải (+ làm cho các ứng dụng khó khăn hơn để duy trì và ít di động?). Nó kinda phụ thuộc vào phần cứng của bạn là tốt, nếu bạn có ít lưu trữ và nó là chậm cũng có lẽ tốt nhất để dính vào nhị phân (20) nếu không tôi muốn nói char (40). Thật khó để nói mà không cần chạy một số thử nghiệm với ngôn ngữ và phần cứng bạn muốn sử dụng và xem những gì phù hợp với bạn nhất. –

+1

Tôi cho rằng nếu bạn đang làm bất cứ điều gì khác hơn là chọn từ nơi unhex (băm) = băm để tìm một hàng, thì có lẽ bạn đã đúng. Nhưng việc giữ chỉ số được đệm sẽ chiếm gấp đôi bộ nhớ theo cách này. – nickdnk

8

Reference taken from this blog:

Dưới đây là danh sách các thuật toán băm cùng với kích thước chút đòi hỏi của nó:

  • MD5 = 128-bit giá trị băm.
  • SHA1 = Giá trị băm 160 bit.
  • SHA224 = giá trị băm 224 bit.
  • SHA256 = Giá trị băm 256 bit.
  • SHA384 = Giá trị băm 38 bit.
  • SHA512 = Giá trị băm 512 bit.

Tạo bảng một mẫu với yêu cầu CHAR (n):

CREATE TABLE tbl_PasswordDataType 
(
    ID INTEGER 
    ,MD5_128_bit CHAR(32) 
    ,SHA_160_bit CHAR(40) 
    ,SHA_224_bit CHAR(56) 
    ,SHA_256_bit CHAR(64) 
    ,SHA_384_bit CHAR(96) 
    ,SHA_512_bit CHAR(128) 
); 
INSERT INTO tbl_PasswordDataType 
VALUES 
(
    1 
    ,MD5('SamplePass') 
    ,SHA1('SamplePass') 
    ,SHA2('SamplePass',224) 
    ,SHA2('SamplePass',256) 
    ,SHA2('SamplePass',384) 
    ,SHA2('SamplePass',512) 
); 
+5

Xin vui lòng, _please_, _ ** xin vui lòng ** _ không thực sự lưu trữ mật khẩu như thế này. –

+0

Hey berry, bạn có thể giải thích tại sao?chi tiết – Anvesh

+2

Việc lưu trữ các mật khẩu đơn giản giúp mật khẩu được trích xuất dễ dàng hơn nếu cơ sở dữ liệu của bạn bị xâm phạm nếu bạn sử dụng mật khẩu băm (hy vọng kéo dài). Đề xuất đọc: https://paragonie.com/blog/2016/02/how-safely-store-password-in-2016 – matt

Các vấn đề liên quan