lưu ý: Tôi biết sử dụng hợp cụ thể lệch OP, nhưng tôi nghĩ rằng nó có thể giúp đỡ những người khác có một tình huống hơi khác nhau
Rất nhiều có thể nói về lý do để chuyển đổi một mảng byte mật mã thành một chuỗi, nhưng thường là cho một số loại mục đích tuần tự hóa; và do đó, trong trường hợp đó: bộ ký tự được chọn là tùy ý.
Vì vậy, nếu và chỉ khi trường hợp trước là đúng VÀ độ dài của chuỗi không bắt buộc phải được tối ưu hóa; bạn có thể sử dụng một đại diện thập lục phân đơn giản của mảng byte như thế này:
//note: since the choice of characters [0..9a..zA...Z] is arbitrary,
//limiting to [0..9,A..F] would seem to be a really big problem if it can be compensated
//by the length.
var rnd = new RNGCryptoServiceProvider();
var sb = new StringBuilder();
var buf = new byte[10]; //length: should be larger
rnd.GetBytes(buf);
//gives a "valid" range of: "ABCDEF"
foreach (byte b in buf)
sb.AppendFormat("{0:x2}", b);
//sb contains a RNGCryptoServiceProvider based "string"
Bây giờ bạn sẽ nói: nhưng đợi: đây chỉ là 16 ký tự nơi chuỗi OP của có 62. chuỗi của bạn sẽ lâu hơn rất nhiều.
"Yes", tôi sẽ trả lời, "và nếu đó là một vấn đề, tại sao bạn không chọn 256 dễ đọc-and-serrializable-nhân vật ... hoặc có lẽ 64"; -)
Như @Guffa đã nêu; sử dụng %
bị cấm trừ khi nó không thay đổi phân phối. Để thực hiện điều này, với tập hợp được phân phối đồng đều, tập con phải phù hợp chính xác x lần trong tập hợp gốc.
Vì vậy, mở rộng tập hợp hợp lệ ban đầu của bạn với 2 cho kết quả hợp lệ (vì: 256/64 = 4).
Mã này sẽ là:
//note: added + and/chars. could be any of them
const string valid = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890+/";
var rnd = new RNGCryptoServiceProvider();
var sb = new StringBuilder();
var buf = new byte[10]; //length: should be larger
rnd.GetBytes(buf); //get the bytes
foreach (byte b in buf)
sb.Append(valid[b%64]);
Xin lưu ý: trong tất cả các câu trả lời, trong đó có một này, các tiểu bộ nhỏ hơn 256 khả năng của byte. Điều này có nghĩa là có ít thông tin hơn. Điều này có nghĩa nếu bạn có chuỗi của bạn với 4 ký tự, nó dễ dàng hơn để crack kết quả 4 byte ban đầu của RNGCryptoServiceProvider.
Vì vậy, ... bây giờ bạn nói: "Tại sao không sử dụng 64 mã hóa cơ sở?", tốt, nếu nó phù hợp với bạn, nhưng hãy cẩn thận với trailing =
, xem Base64 on Wikipedia:
var rnd = new RNGCryptoServiceProvider();
var buf = new byte[60]; //length not randomly picked, see 64Base, wikipedia
rnd.GetBytes(buf);
string result = Convert.ToBase64String(buf);
Hãy note²: Một trường hợp sử dụng điển hình là một số url token. Xin lưu ý rằng dấu hiệu +
không hợp lệ như một ký tự như vậy.
Bạn phải cẩn thận khi bạn chuyển đổi các giá trị byte thành một số trong một phạm vi cụ thể. Nếu bạn chỉ sử dụng '%' thì nó sẽ tạo ra các số có phân phối không đồng đều, và toàn bộ mục đích của việc sử dụng một trình tạo ngẫu nhiên tốt hơn là vô nghĩa. – Guffa
Đó là sự thật, muốn thêm điều đó sau khi tôi đăng câu trả lời của mình. Câu trả lời của Tamir Vered là khá thú vị mặc dù khủng khiếp không hiệu quả vì nó không sử dụng StringBuilder. Nó bỏ qua các byte không được chấp nhận làm đầu vào, đó là một giải pháp thú vị và sẽ có một phân phối thích hợp như là – hl3mukkel