Random 加密洗牌和挑选
我正在实现一个加密安全的洗牌例程,有几个问题: 我使用的方法是加权排序,其中每个权重是一个加密强随机数Random 加密洗牌和挑选,random,Random,我正在实现一个加密安全的洗牌例程,有几个问题: 我使用的方法是加权排序,其中每个权重是一个加密强随机数 我使用列表中的项数(X)计算每个权重所需的位数,并将其插入以下公式=log10(X!)/log10(2)。例如,52卡组需要log10(52!)/log10(2)=225.58100312370276194634244437667位/重量。我总是把它四舍五入,因为一点点的分数是不能表示的。我总是四舍五入是正确的,还是给了我太多的比特 从硬件rng检索位可能不太实际,因此必须检索字节。与前面的示
log10(X!)/log10(2)
。例如,52卡组需要log10(52!)/log10(2)=225.58100312370276194634244437667
位/重量。我总是把它四舍五入,因为一点点的分数是不能表示的。我总是四舍五入是正确的,还是给了我太多的比特Imports System.Security.Cryptography
Module Module1
Public Class Ball
Public Weight As String
Public Value As Integer
Public Sub New(ByVal _Weight As String, ByVal _Value As Integer)
Weight = _Weight
Value = _Value
End Sub
End Class
Public Class BallComparer_Weight
Implements IComparer(Of Ball)
Public Function Compare(x As Ball, y As Ball) As Integer Implements System.Collections.Generic.IComparer(Of Ball).Compare
If x.Weight > y.Weight Then
Return 1
ElseIf x.Weight < y.Weight Then
Return -1
Else
Return 0
End If
End Function
End Class
Public Class BallComparer_Value
Implements IComparer(Of Ball)
Public Function Compare(x As Ball, y As Ball) As Integer Implements System.Collections.Generic.IComparer(Of Ball).Compare
If x.Value > y.Value Then
Return 1
ElseIf x.Value < y.Value Then
Return -1
Else
Return 0
End If
End Function
End Class
Public Function Weight(ByVal rng As RNGCryptoServiceProvider, ByVal bits As Integer) As String
' generate a "cryptographically" random string of length 'bits' (should be using hardware rng)
Dim remainder As Integer = bits Mod 8
Dim quotient As Integer = bits \ 8
Dim byteCount As Integer = quotient + If(remainder <> 0, 1, 0)
Dim bytes() As Byte = New Byte(byteCount - 1) {}
Dim result As String = String.Empty
rng.GetBytes(bytes)
For index As Integer = bytes.Length - 1 To 0 Step -1
If index = bytes.Length - 1 Then
' remove upper `remainder` bits from upper byte
Dim value As Byte = (bytes(0) << remainder) >> remainder
result &= value.ToString("X2")
Else
result &= bytes(index).ToString("X2")
End If
Next
Return result
End Function
Public Function ContainsValue(ByVal lst As List(Of Ball), ByVal value As Integer) As Boolean
For i As Integer = 0 To lst.Count - 1
If lst(i).Value = value Then
Return True
End If
Next
Return False
End Function
Sub Main()
Dim valueComparer As New BallComparer_Value()
Dim weightComparer As New BallComparer_Weight()
Dim picks As New List(Of Ball)
Dim balls As New List(Of Ball)
' number of bits after each "ball" is drawn
Dim bits() As Integer = New Integer() {364, 358, 351, 345, 339}
Using rng As New RNGCryptoServiceProvider
While True
picks.Clear()
' simulate random balls
'log10(75!) / log10(2) = number of bits required for weighted random shuffle (reduces each time ball is pulled) = 363.40103411549404253061653790169 = 364
For i As Integer = 0 To 4
balls.Clear()
For value As Integer = 1 To 75
' do not add previous picks
If Not ContainsValue(picks, value) Then
balls.Add(New Ball(Weight(rng, bits(i)), value))
End If
Next
balls.Sort(weightComparer)
'For Each x As Ball In balls
' Console.WriteLine(x.Weight)
'Next
'Console.ReadLine()
' choose first ball in sorted list
picks.Add(balls(0))
Next
picks.Sort(valueComparer)
' simulate random balls
'log10(15!) / log10(2) = number of bits required for weighted random shuffle = 40.250140469882621763813506287601 = 41 bits required for megaball
balls.Clear()
For value As Integer = 1 To 15
balls.Add(New Ball(Weight(rng, 41), value))
Next
balls.Sort(weightComparer)
' print to stdout
For i As Integer = 0 To 4
Console.Write(picks(i).Value.ToString("D2") & " "c)
Next
Console.WriteLine(balls(0).Value.ToString("D2"))
End While
End Using
End Sub
End Module
导入System.Security.Cryptography
模块1
公共班级舞会
作为弦的公共重量
作为整数的公共值
Public Sub New(ByVal\u权重为字符串,ByVal\u值为整数)
重量=_重量
值=\u值
端接头
末级
公共级球形比较器
机具(球的)比较器
公共函数Compare(x为Ball,y为Ball)作为整数实现System.Collections.Generic.IComparer(Of Ball).Compare
如果x.重量>y.重量,则
返回1
如果x.重量小于y.重量,则
返回-1
其他的
返回0
如果结束
端函数
末级
公共类BallComparer_值
机具(球的)比较器
公共函数Compare(x为Ball,y为Ball)作为整数实现System.Collections.Generic.IComparer(Of Ball).Compare
如果x值>y值,则
返回1
如果x值小于y值,则
返回-1
其他的
返回0
如果结束
端函数
末级
作为字符串的公共函数权重(ByVal rng作为RNGCryptoServiceProvider,ByVal位作为整数)
'生成长度为'位'的“加密”随机字符串(应使用硬件rng)
将余数调整为整数=位Mod 8
整数形式的小商=位\8
作为整数的Dim字节计数=商+If(余数0,1,0)
Dim bytes()作为Byte=新字节(字节计数-1){
Dim结果为String=String.Empty
rng.GetBytes(字节)
对于作为整数的索引=字节。长度-1到0步骤-1
如果index=bytes.Length-1,则
'从高位字节中删除高位`余数'位
Dim值为字节=(字节(0)>余数
结果&=value.ToString(“X2”)
其他的
结果&=字节(索引).ToString(“X2”)
如果结束
下一个
返回结果
端函数
公共函数包含布尔值(ByVal lst作为列表(球),ByVal值作为整数)
对于i作为整数=0到lst.Count-1
如果lst(i).Value=Value,则
返回真值
如果结束
下一个
返回错误
端函数
副标题()
Dim valueComparer作为新的BallComparer_值()
Dim weightComparer作为新的Ballcomarer_Weight()
将拾取的球变暗为新列表(球)
将球调暗为新列表(球)
'每个“球”绘制后的位数
Dim bits()作为整数=新整数(){364,358,351,345,339}
将rng用作新的RNGCryptoServiceProvider
虽然是真的
1.Clear()
'模拟随机球
'log10(75!)/log10(2)=加权随机洗牌所需的位数(每次拉球时减少)=363.40103411549404253061653790169=364
对于i,整数=0到4
球
对于整数形式的值=1到75
'不要添加以前的拾取
如果不包含value(picks,value),则
球。添加(新球(重量(rng,位(i)),值))
如果结束
下一个
球.分类(重量比较器)
'对于每个x作为球中的球
'控制台写入线(x重量)
”“接着呢
'Console.ReadLine()
'选择排序列表中的第一个球
拾取。添加(球(0))
下一个
picks.Sort(valueComparer)
'模拟随机球
'log10(15!)/log10(2)=加权随机洗牌所需的位数=40.250140469882621763813506287601=megaball所需的41位