I wouldn't do it bit-by-bit; I'd generate 32 bits at a time. You'll need to generate 10x32 integers (1024=32x32), then just plug them into the array.
Algorithm:
0) Instantiate a HashSet<int> and a Queue<int>
1) Get Random.Next()
2) If the new int is not in the Hashset, then add it to the Hashset and Queue
3) If fewer than 320 ints in the Queue, goto 1
4) Iterate 10 rows by 32 ints per row
5) Dequeue the next int
6) Get the base-2 representation of the value
System.Convert.ToString ( intval , 2 ).PadLeft ( 32 , '0' )
7) Append (see StringBuilder) the string to the current row
A limitation of this technique is that the most-significant bit of each int will always be zero. If that is a concern, you could do sixteen bits at a time instead. Or try NextBytes:
http://msdn.microsoft.com/en-us/library/vstudio/system.random.nextbytes(v=vs.100).aspx[
^]
I would also like to point out that the larger the things compared, the smaller the difference is required. So if you produce 10 full 1024-bit values, then any two values may differ by only one bit (although that has a small probability).
By generating 320 32-bit values I believe the resultant 1024-bit values are guaranteed to differ by at least 32 bits. And if you use 64 16-bit values, then you can expect at least 64 differences.
If the number of differences matters, then you may need to calculate the Levenshtein Distance and compare to some threshold rather than a simple equal/not-equal check.
P.S. I see that I got the shape of the array reversed, no big deal. Generate all the values from 0 to 1023 and then put them into the array in random order:
int[] a = new int [ 1024 ] ;
for ( int i = 0 ; i < a.Length ; i++ ) a [ i ] = i ;
System.Collections.Generic.List<string> s =
new System.Collections.Generic.List<string> ( a.Length ) ;
foreach ( int i in a.OrderBy ( x => System.Guid.NewGuid() ) )
s.Add ( System.Convert.ToString ( i , 2 ).PadLeft ( 10 , '0' ) ) ;