14/03/10 8:55
Il Totem
Posterò a breve una classe di esempio per generare e validare seriali. Ma nel frattempo ricordo che in questa sezione non si presentano lavori completi. Per quello c'è l'opzione di upload, almeno se si è membri.
aaa
15/03/10 17:22
Il Totem
Ecco l'esempio:
''' <summary> ''' Questa classe deve essere tenuta nascosta. Serve per generare un codice ''' seriale e/ verificarne la correttezza. ''' </summary> Public Class CodeGenerator Private _CodeRank As Int16 = 8 Private _DerivingIterations As Int16 = 5 Private _SaltBytes As Byte() Private Shared ReadOnly Rnd As Random ''' <summary> ''' Definisce la forza del codice, direttamente legata alla sua lunghezza. Minimo 3. ''' </summary> Public Property CodeRank() As Int16 Get Return _CodeRank End Get Set(ByVal value As Int16) If value >= 3 Then _CodeRank = value Else _CodeRank = 3 End If End Set End Property ''' <summary> ''' Salt crittografico. Questo array di bytes viene usato per derivare il codice finito. ''' E' il punto di forza dell'algoritmo, in quanto ogni programmatore che usa questa classe ''' può utilizzare un array di bytes diverso da tutti gli altri, e ciò produrra anche un ''' risultato diverso. Questo sorgente, quindi, è riusabile al 100%. ''' </summary> Public Property SaltBytes() As Byte() Get Return _SaltBytes End Get Set(ByVal value As Byte()) _SaltBytes = value End Set End Property ''' <summary> ''' Numero di iterazioni compiute dall'algoritmo di derivazione. Anche questo è un fattore ''' cambiando il quale cambia il risultato. ''' </summary> Public Property DerivingIterations() As Int16 Get Return _DerivingIterations End Get Set(ByVal value As Int16) If value >= 2 Then _DerivingIterations = value Else _DerivingIterations = 2 End If End Set End Property Shared Sub New() Rnd = New Random() End Sub ''' <summary> ''' Randomizza i parametri del generatore. NOTA BENE: per verificare un codice seriale, è ''' necessario che il generatore mantenga le stesse proprietà dell'oggetto che ha creato il codice. ''' Quindi non bisogna abusare di questa funzione. ''' </summary> Public Sub Randomize() Me.CodeRank = Rnd.Next(6, 14) Me.DerivingIterations = Rnd.Next(2, 10) Dim Bytes(Rnd.Next(10, 40)) As Byte For I As Int16 = 0 To Bytes.Length - 1 Bytes(I) = Rnd.Next(0, 256) Next Me.SaltBytes = Bytes End Sub ''' <summary> ''' Genera un codice seriale esadecimale casuale basandosi sui dati immessi nelle proprietà ''' della classe. ''' </summary> Public Function GenerateCode() As String Dim Derive As Rfc2898DeriveBytes Dim DerivedBytes() As Byte Dim Result As New System.Text.StringBuilder Dim RandomSequence(Me.CodeRank - 1) As Byte For I As Int16 = 0 To RandomSequence.Length - 1 RandomSequence(I) = Rnd.Next(0, 256) Next Derive = New Rfc2898DeriveBytes(RandomSequence, Me.SaltBytes, Me.DerivingIterations) DerivedBytes = Derive.GetBytes(Me.CodeRank) For I As Int16 = 0 To Me.CodeRank - 1 Result.AppendFormat("{0:X2}{1:X2}", RandomSequence(I), DerivedBytes(I)) Next Derive = Nothing DerivedBytes = Nothing RandomSequence = Nothing Return Result.ToString() End Function ''' <summary> ''' Controlla se il codice immesso è valido. Restituisce True in caso di validità. ''' </summary> ''' <param name="Code">Codice seriale proposto per la verifica.</param> Public Function ValidateCode(ByVal Code As String) As Boolean Dim OriginalCode As String = Regex.Replace(Code, "[\w\W-[A-Z0-9]]", "", RegexOptions.IgnoreCase) Dim RandomSequence(Me.CodeRank - 1), CodeBytes(Me.CodeRank - 1), DerivedBytes() As Byte Dim Derive As Rfc2898DeriveBytes If OriginalCode.Length <> Me.CodeRank * 4 Then Return False End If For I As Int16 = 0 To Me.CodeRank - 1 Try RandomSequence(I) = Int32.Parse(OriginalCode.Substring(I * 4, 2), Globalization.NumberStyles.AllowHexSpecifier) CodeBytes(I) = Int32.Parse(OriginalCode.Substring(I * 4 + 2, 2), Globalization.NumberStyles.AllowHexSpecifier) Catch Ex As Exception Return False End Try Next Derive = New Rfc2898DeriveBytes(RandomSequence, Me.SaltBytes, Me.DerivingIterations) DerivedBytes = Derive.GetBytes(Me.CodeRank) OriginalCode = Nothing Derive = Nothing RandomSequence = Nothing For I As Int16 = 0 To Me.CodeRank - 1 If CodeBytes(I) <> DerivedBytes(I) Then Return False End If Next CodeBytes = Nothing DerivedBytes = Nothing Return True End Function ''' <summary> ''' Spezza il codice in parti di lunghezza specificata. ''' </summary> Public Shared Function SplitCode(ByVal Code As String, ByVal ParamArray Lengths() As Int16) As String() Dim CodeReader As New IO.StringReader(Code) Dim Result As New List(Of String) Dim Buffer() As Char For Each Len As Int16 In Lengths ReDim Buffer(Len - 1) If CodeReader.ReadBlock(Buffer, 0, Len) > 0 Then Result.Add(Buffer) Else Exit For End If Next Return Result.ToArray() End Function End Class
aaa