Hasilkan Jumlah Data Acak yang Tepat di C#

Saya memerlukan cara untuk menghasilkan data psuedo-acak (string) dalam jumlah yang tepat. Misalnya, saya ingin membuat kode metode yang mengambil argumen untuk jumlah byte yang akan dihasilkan dan mengembalikan string dengan ukuran yang tepat.

Saya awalnya bermaksud untuk hanya menghasilkan 1 karakter per byte yang dibutuhkan, tetapi ternyata karakter tidak lagi semuanya satu byte.

Bantuan apa pun dihargai!


person Razick    schedule 26.09.2012    source sumber
comment
Sebuah string dibatasi untuk sekumpulan karakter tertentu?   -  person Alex K.    schedule 26.09.2012
comment
mengukur string yang ada untuk menentukan jumlah byte yang tepat - sekali lagi, ini bukan lagi semua byte.   -  person Henk Holterman    schedule 26.09.2012
comment
@AlexK. Tidak juga, hanya data string acak.   -  person Razick    schedule 26.09.2012
comment
@Henk Holterman Saya harus bisa menghasilkan data acak, dengan kata lain harus berbeda setiap saat. Jadi selain menggunakan beberapa string mini, katakanlah sepanjang 10 byte dan merakitnya secara acak, itu tidak akan berhasil, dan itu bukan solusi yang bagus bagi saya.   -  person Razick    schedule 26.09.2012
comment
Sebuah string tidak mengandung byte sama sekali, melainkan karakter. Sebuah karakter menggunakan dua byte dalam memori, tapi menurut saya bukan itu yang Anda cari. Anda juga dapat mengkodekan string ke dalam byte, tetapi panjangnya berbeda-beda tergantung pada pengkodean yang digunakan. Apa tujuan mendapatkan string yang sesuai (dalam beberapa hal) dengan sejumlah byte? Bagaimana Anda akan menggunakannya?   -  person Guffa    schedule 26.09.2012
comment
Hubungan antara data dan teks tampak sedikit kabur di sini. Apakah string merupakan hasil akhir atau sarana untuk mendapatkan byte?   -  person Henk Holterman    schedule 26.09.2012
comment
@HenkHolterman String adalah hasil akhirnya.   -  person Razick    schedule 26.09.2012
comment
Oke, dan apakah Anda memenuhi persyaratan ukuran tentang jumlah karakter atau jumlah byte?   -  person Henk Holterman    schedule 26.09.2012
comment
@Guffa Saya pikir pengkodean modern seperti unicode dan utf-8 sebenarnya berukuran cukup. (Tidak semua karakter menggunakan jumlah ruang yang sama. Agak sulit menjelaskan cara saya menggunakannya, tetapi data acak dimasukkan ke dalam file untuk dijadikan sebagai pengganti data sebenarnya.   -  person Razick    schedule 26.09.2012
comment
@HenkHolterman Saya tidak begitu yakin dengan maksud Anda, tetapi hasil akhirnya (string) harus berukuran tepat dalam byte.   -  person Razick    schedule 26.09.2012
comment
ukurannya harus tepat dalam byte - sekarang Anda bertentangan dengan diri Anda sendiri. String berisi karakter dan bukan byte. sizeof(char) == 2 * sizeof(byte)   -  person Henk Holterman    schedule 26.09.2012
comment
Maksud saya, saya ingin kemampuan menghasilkan, katakanlah 1kb data teks acak. Ukuran karakter individu tidak relevan.   -  person Razick    schedule 26.09.2012
comment
Agak mudah untuk membuat string yang akan menggunakan jumlah byte tertentu saat dikodekan, tetapi sepertinya Anda ingin membuat placeholder yang akan menggunakan jumlah byte yang sama dengan jumlah string arbitrer, dan itu tidak mungkin karena jumlah byte tersebut akan bergantung pada isi string tersebut, dan hal tersebut belum diketahui.   -  person Guffa    schedule 26.09.2012
comment
@Guffa Bukan itu masalahnya. String acak akan terus mengisi file setelah titik di mana string penggantinya berakhir.   -  person Razick    schedule 27.09.2012
comment
@Razick: Oke, kalau begitu mudah. :)   -  person Guffa    schedule 27.09.2012


Jawaban (3)


Saya sarankan menggunakan RNGCryptoServiceProvider karena dapat menghasilkan sebanyak mungkin byte acak sesuai keinginan Anda. Anda kemudian dapat mengonversinya menjadi string (misalnya menggunakan pengkodean byte64 atau metode lain).

Ingatlah untuk menambahkan using System.Security.Cryptography; ke file.

public class RandomService : IDisposable
{
    private readonly RNGCryptoServiceProvider rngCsp;

    public CryptoService()
    {
        rngCsp = new RNGCryptoServiceProvider();            
    }

    public byte[] GetRandomBytes(int length)
    {
        var bytes = new byte[length];
        rngCsp.GetBytes(bytes);
        return bytes;
    }

    public string GetRandomString(int length)
    {
        var numberOfBytesForBase64 = (int) Math.Ceiling((length*3)/4.0);
        string base64String = Convert.ToBase64String(GetRandomBytes(numberOfBytesForBase64)).Substring(0, length); //might be longer because of padding            
        return base64String.Replace('+', '_').Replace('/', '-'); //we don't like these base64 characters
    }

    public void Dispose()
    {
        rngCsp.Dispose();
    }
}
person empi    schedule 26.09.2012
comment
Apakah ukurannya tetap sama ketika diubah menjadi string? - person Razick; 26.09.2012
comment
Anda mendapatkan sekitar 8/6 karakter per byte. - person Henk Holterman; 26.09.2012
comment
@Razick: basis 64 lebih panjang dari array byte awal. Periksa pembaruan saya - Saya telah memberikan kode contoh. - person empi; 26.09.2012
comment
Terima kasih, saya akan mencobanya. - person Razick; 26.09.2012
comment
RNG sangat acak tetapi mungkin juga memerlukan upaya berlebihan untuk membuat beberapa data pengujian. Bahkan menjadi masalah jika membutuhkan data sebanyak itu. `Random.NextBytes()' mungkin akan berfungsi dengan baik. - person Henk Holterman; 26.09.2012
comment
@HenkHolterman: ya, itu benar. Saya menggunakan kelas ini dalam skenario di mana saya memerlukan data acak secara kriptografis (khususnya id sesi). Namun, Anda dapat mengubah implementasi GetRandomBytes dan meninggalkan GetRandomString untuk penerjemahan. - person empi; 26.09.2012
comment
@HenkHolterman Ini bekerja dengan sangat baik, saya akan mencoba saran Anda dan melihat apakah saya mendapatkan kecepatan yang lebih baik. - person Razick; 26.09.2012
comment
@HenkHolterman Tidak banyak peningkatan kecepatan, tapi sedikit lebih bersih jadi saya akan menggunakannya. Terima kasih. - person Razick; 26.09.2012

Anda mungkin dapat mengambil kelas Acak, mengonversi ke byte[] lalu ToString()

person Amelia    schedule 26.09.2012
comment
Meskipun setiap string dapat dikonversi menjadi byte[], tidak setiap byte[] dapat dikonversi menjadi string. - person dtb; 26.09.2012
comment
@dtb: setiap byte[] dapat dikonversi menjadi string (mis. base64 atau terjemahan sewenang-wenang). - person empi; 26.09.2012
comment
Namun seperti namanya, ini hanya menggunakan 64 karakter berbeda. Ada lebih dari itu di dunia Unicode. - person Henk Holterman; 26.09.2012
comment
64 kemungkinan karakter sebenarnya akan baik-baik saja. - person Razick; 26.09.2012

Jika Anda menggunakan sekumpulan karakter terbatas, Anda dapat memilih karakter yang akan dijadikan kode byte tunggal, apa pun pengkodean yang digunakan.

public byte[] CreateFiller(int length, Random rnd) {
  string chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
  return Encoding.UTF8.GetBytes(Enumerable.Range(0, length).Select(i => chars[rnd.Next(chars.Length)]).ToArray());
}

// only use the overload that creates a Random object itself if you use it once, not in a loop
public byte[] CreateFiller(int length) {
  return CreateFiller(length, new Random());
}
person Guffa    schedule 26.09.2012