ErrorsManager/VB/ErrorsManager.vb

626 lines
23 KiB
VB.net

Imports System
Imports System.Collections.Generic
Imports System.Text
Imports System.Text.RegularExpressions
Imports System.Linq
Namespace ErrorsManager
Public Class ErrorsManager
Public Shared ReadOnly ALPHABET As Char() = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/=".ToCharArray()
Public Shared ReadOnly ERRORS_MESSAGES As String() = New String(){
"invalid_alphabet",
"invalid_base",
"invalid_alphabet_type",
"too_short_alphabet",
"repeated_characters_in_alphabet",
"too_long_alphabet",
"base_lower_than_2",
"base_greater_than_128",
"base_greater_than_alphabet"
}
Public Shared ReadOnly RE_KEY As New Regex("^[a-zA-Z0-9_]+$", RegexOptions.IgnoreCase Or RegexOptions.Compiled)
Private _error As Integer = 0
Private _alphabet As Char() = New Char(){}
Private dictionary As New Dictionary(Of Char, Byte)()
Private _base As Byte
Private power As Byte
Public Sub New(Optional inputs As Object = Nothing)
set_alphabet(
ErrorsManager.[get](Of Object)("alphabet", inputs, ALPHABET),
ErrorsManager.[get](Of Integer)("base", inputs, 64)
)
end Sub
Public Function set_alphabet(alphabet As Object, Optional _base As Integer = 64) As Integer
Dim original_length As Integer
_error = 0
If alphabet Is Nothing Then
_alphabet = ALPHABET
ElseIf TypeOf alphabet Is String Then
_alphabet = DirectCast(alphabet, String).ToCharArray()
ElseIf TypeOf alphabet Is IEnumerable(Of Char) Then
_alphabet = DirectCast(alphabet, IEnumerable(Of Char)).ToArray()
Else
_error = _error Or (1 << 0)
Return _error
End If
original_length = _alphabet.Length
_alphabet = _alphabet.Distinct().ToArray()
If _alphabet.Length < 2 Then
_error = _error Or (1 << 3)
_alphabet = ALPHABET
End If
If _alphabet.Length <> original_length Then _error = _error Or (1 << 4)
If _alphabet.Length > 128 Then _error = _error Or (1 << 5)
_error = _error Or (
If(_base < 2, 1 << 0,
If(_base > 128, 1 << 1,
If(_base > _alphabet.Length, 1 << 2,
0)))) << 6
If (_error >> 6) = 0 Then _alphabet = _alphabet.Take(_base).ToArray()
power = CByte(Math.Truncate(Math.Log(_alphabet.Take(128).Count(), 2)))
Me._base = CByte(Math.Truncate(Math.Pow(2, power)))
_alphabet = _alphabet.Take(Me._base).ToArray()
dictionary.Clear()
For i As Byte = 0 To _alphabet.Length - 1
dictionary(_alphabet(i)) = i
Next
Return _error
End Function
Public Function get_alphabet() As String
Return New String(_alphabet)
End Function
Public Function to_array(code As String) As Byte()
Return code.Select(Function(character) dictionary(character)).ToArray()
End Function
Public Function to_array(code As Byte()) As Byte()
Return code
End Function
Public Function to_array(code As Integer) As Byte()
Dim hexas As New List(Of Byte)()
While code > 0
hexas.Add(CByte(code Mod _base))
code \= _base
End While
Return hexas.ToArray()
End Function
Public Function to_string(code As Byte()) As String
Return New String(code.Select(Function(hexa) _alphabet(hexa)).ToArray())
End Function
Public Function to_string(code As Integer) As String
Dim hexas As New StringBuilder()
While code > 0
hexas.Append(_alphabet(code Mod _base))
code \= _base
End While
Return hexas.ToString()
End Function
Public Function to_string(code As String) As String
Return code
End Function
Public Function to_integer(code As Byte()) As Integer
Dim _integer As Integer = 0
For i As Integer = code.Length - 1 To 0 Step -1
_integer = _integer * _base + code(i)
Next
Return _integer
End Function
Public Function to_integer(code As String) As Integer
Dim _integer As Integer = 0
For i As Integer = code.Length - 1 To 0 Step -1
_integer = _integer * _base + dictionary(code(i))
Next
Return _integer
End Function
Public Function to_integer(code As Integer) As Integer
Return code
End Function
Public Function to_string_binary(code As Byte()) As String
Return String.Concat(code.Reverse().Select(Function(hexa) Convert.ToString(hexa, 2).PadLeft(power, "0"c)))
End Function
Public Function to_string_binary(code As Integer) As String
Dim binary As String = Convert.ToString(code, 2)
Dim remainer As Integer = binary.Length Mod power
Return If(remainer = 0, binary, binary.PadLeft(binary.Length + power - remainer, "0"c))
End Function
Public Function to_string_binary(code As String) As String
Return String.Concat(code.Reverse().Select(Function(character) Convert.ToString(dictionary(character), 2).PadLeft(power, "0"c)))
End Function
Public Function get_bits(code As String) As Integer
Return If(code.Length = 0, 0, (code.Length - 1) * power + CInt(Math.Ceiling(Math.Log(dictionary(code.Last()) + 1, 2))))
End Function
Public Function get_bits(code As Byte()) As Integer
Return If(code.Length = 0, 0, (code.Length - 1) * power + CInt(Math.Ceiling(Math.Log(code.Last() + 1, 2))))
End Function
Public Function get_bits(code As Integer) As Integer
Return CInt(Math.Ceiling(Math.Log(code + 1, 2)))
End Function
Public Sub get_from_bits(code As String, ByRef [from] As Integer, ByRef bits As Integer)
get_from_bits(to_array(code), from, bits)
End Sub
Public Sub get_from_bits(code As Byte(), ByRef [from] As Integer, ByRef bits As Integer)
If [from] < 0 Then
[from] = get_bits(code) + from
If [from] < 0 Then [from] = 0
End If
If bits < 0 Then
[from] += bits
bits *= -1
If [from] < 0 Then
bits += [from]
[from] = 0
End If
End If
End Sub
Public Sub get_from_bits(code As Integer, ByRef [from] As Integer, ByRef bits As Integer)
get_from_bits(to_array(code), [from], bits)
End Sub
Public Function clean(code As String) As String
Dim l As Integer = code.Length
While l > 0 AndAlso code(l - 1) = _alphabet(0)
l -= 1
End While
Return (
If(code.Length = l, code,
If(l = 0, _alphabet(0).ToString(),
code.Substring(0, l))))
End Function
Public Function clean(code As Byte()) As Byte()
Dim l As Integer = code.Length
While l > 0 AndAlso code(l - 1) = 0
l -= 1
End While
Return (
If(code.Length = l, code,
If(l = 0, New Byte(){0},
code.Take(l).ToArray())))
End Function
Public Function clean(code As Integer) As Integer
Return code
End Function
Public Function get_range(code As String, [from] As Integer, bits As Integer) As String
Return to_string(get_range(to_array(code), [from], bits))
End Function
Public Function get_range(code As Byte(), [from] As Integer, bits As Integer) As Byte()
Dim hexas As List(Of Byte)
get_from_bits(code, [from], bits)
If bits = 0 Then bits = get_bits(code) - [from]
If bits <= 0 Then Return New Byte(){}
hexas = code.ToList()
If [from] > 0 Then
Dim shift As Byte = CByte([from] Mod power)
Dim mask As Integer = CInt((1 << shift) - 1)
hexas = hexas.Skip([from] \ power).ToList()
If shift <> 0 AndAlso hexas.Count() > 0 Then
Dim l = hexas.Count() - 2
For i As Integer = 0 To l
hexas(i) = CByte((hexas(i) >> shift) Or ((hexas(i + 1) << (power - shift)) And mask))
Next
hexas(l + 1) = CByte(hexas(l + 1) >> shift)
End If
End If
If bits > 0 Then
Dim shift As Byte = CByte(bits Mod power)
hexas = hexas.Take(CInt(Math.Ceiling(bits / CDbl(power)))).ToList()
If shift <> 0 AndAlso hexas.Count() > 0 Then
hexas(hexas.Count() - 1) = CByte(hexas.Last() And ((1 << shift) - 1))
End If
End If
Return clean(hexas.ToArray())
End Function
Public Function get_range(code As Integer, [from] As Integer, bits As Integer) As Integer
get_from_bits(code, [from], bits)
If [from] > 0 Then code = (code >> [from]) And ((1 << (31 - [from])) - 1)
If bits <= 0 OrElse bits >= 31 Then Return code
If [from] + bits > 31 Then bits = 31 - [from]
Return code And ((1 << bits) - 1)
End Function
Public Function process(code As String, messages As IEnumerable(Of String), Optional blocks As Dictionary(Of Integer, Integer) = Nothing) As (Integer, String)()
Return process(to_array(code), messages, blocks)
End Function
Public Function process(code As Byte(), messages As IEnumerable(Of String), Optional blocks As Dictionary(Of Integer, Integer) = Nothing) As (Integer, String)()
Dim response As new List(Of (Integer, String))()
Dim k As Integer = 0
Dim l = code.Length * power
Dim i As Integer = 0
Dim m As Integer = messages.Count()
If blocks Is Nothing Then blocks = New Dictionary(Of Integer, Integer)()
While i < l
If blocks.ContainsKey(i) AndAlso blocks(i) > 0 Then
Dim logarithm As Integer = CInt(Math.Log(blocks(i), 2))
Dim _k As Integer
If logarithm = 0 Then logarithm = 1
_k = to_integer(get_range(code, i, logarithm))
If _k > 0 Then
_k = k + _k
response.Add((_k, If(k < m, messages(k), "")))
End If
k += blocks(i)
i += logarithm
Else
If (code(i \ power) And (1 << i Mod power)) <> 0 Then
response.Add((k, If(k < m, messages(k), "")))
End If
k += 1
i += 1
End If
End While
return response.ToArray()
End Function
Public Function process(code As Integer, messages As IEnumerable(Of String), Optional blocks As Dictionary(Of Integer, Integer) = Nothing) As (Integer, String)()
Return process(to_array(code), messages, blocks)
End Function
Public Function bitwise(code As String, bits As Integer) As String
Return to_string(get_range(to_array(code), 0, bits))
End Function
Public Function bitwise(code As Byte(), bits As Integer) As Byte()
If code.Length = 0 OrElse bits = 0 Then Return code
Dim shift As Byte = CByte(Math.Abs(bits) Mod power)
Dim mask As Integer = _base - 1
Dim hexas As List(Of Byte) = code.ToList()
If bits < 0 Then
hexas.RemoveRange(0, -bits \ power)
If shift <> 0 AndAlso hexas.Count() <> 0 Then
Dim l As Integer = hexas.Count() - 2
For i As Integer = 0 To l
hexas(i) = CByte(((hexas(i) >> shift) Or (hexas(i + 1) << (power - shift))) And mask)
Next
hexas(hexas.Count - 1) = CByte((hexas.Last() >> shift) And mask)
End If
Else
If shift <> 0 Then
Dim last_hexa As Byte = hexas.Last() << shift
For i As Integer = hexas.Count() - 1 To 1 Step -1
hexas(i) = CByte(((hexas(i) << shift) Or (hexas(i - 1) >> (power - shift))) And mask)
Next
hexas(0) = CByte((hexas(0) << shift) And mask)
If last_hexa >= _base Then hexas.Add(CByte(last_hexa >> power))
End If
For i As Integer = bits \ power To 1 Step -1
hexas.Insert(0, 0)
Next
End If
Return clean(hexas.ToArray())
End Function
Public Function bitwise(code As Integer, bits As Integer) As Integer
Return (
If(bits > 0, code << bits,
If(bits < 0, code >> -bits,
code)))
End Function
Public Function reset(code As String, [from] As Integer, Optional bits As Integer = 0, Optional reversed As Boolean = False) As String
Return to_string(reset(to_array(code), [from], bits, reversed))
End Function
Public Function reset(code As Byte(), [from] As Integer, Optional bits As Integer = 0, Optional reversed As Boolean = False) As Byte()
Dim hexas As List(Of Byte) = code.ToList()
Dim hexa_from As Integer
Dim hexa_to As Integer
Dim l As Integer
Dim from_mask As Byte
Dim to_mask As Byte
get_from_bits(code, [from], bits)
hexa_from = [from] \ power
hexa_to = ([from] + bits) \ power
If reversed Then
l = [from] Mod power
from_mask = CByte(((1 << power - l) - 1) << l)
to_mask = Cbyte(((1 << ([from] + bits)) - 1) Mod power)
For i As Integer = 0 To hexas.Count() - 1
If i < hexa_from AndAlso i > hexa_to Then hexas(i) = 0
Next
If hexa_from = hexa_to Then
hexas(hexa_to) = CByte(hexas(hexa_to) And (from_mask Or to_mask))
Else
hexas(hexa_from) = CByte(hexas(hexa_from) And from_mask)
If hexa_to < hexas.Count() Then hexas(hexa_to) = CByte(hexas(hexa_to) And to_mask)
End If
Else
l = ([from] + bits) Mod power
from_mask = CByte((1 << ([from] Mod power)) - 1)
to_mask = CByte(((1 << (power - l)) - 1) << l)
If hexa_from = hexa_to Then
hexas(hexa_to) = CByte(hexas(hexa_to) And (from_mask Or to_mask))
Else
hexas(hexa_from) = CByte(hexas(hexa_from) And from_mask)
For i As Integer = hexa_from + 1 To hexa_to - 1
If i < hexas.Count() Then hexas(i) = 0
Next
If hexa_to < hexas.Count() Then hexas(hexa_to) = CByte(hexas(hexa_to) And to_mask)
End If
End If
Return clean(hexas.ToArray())
End Function
Public Function reset(code As Integer, [from] As Integer, Optional bits As Integer = 0, Optional reversed As Boolean = False) As Integer
get_from_bits(code, [from], bits)
If [from] + bits > 31 Then bits = 31 - [from]
Return code And (
If(reversed, ((1 << bits) - 1) << [from],
((1 << get_bits(code)) << [from] + bits Or ((1 << [from]) - 1))))
End Function
Public Function has(code As String, [from] As Integer, bits As Integer) As Boolean
Return get_range(to_array(code), [from], bits).Length > 0
End Function
Public Function has(code As Byte(), [from] As Integer, bits As Integer) As Boolean
Return get_range(code, [from], bits).Length > 0
End Function
Public Function has(code As Integer, [from] As Integer, bits As Integer) As Boolean
Return get_range(code, [from], bits) <> 0
End Function
Public Function [set]([error] As String, code As String, Optional [from] As Integer = 0, Optional bits As Integer = 0) As String
Return to_string([set](to_array([error]), to_array(code), [from], bits))
End Function
Public Function [set]([error] As String, code As Byte(), Optional [from] As Integer = 0, Optional bits As Integer = 0) As String
Return to_string([set](to_array([error]), code, [from], bits))
End Function
Public Function [set]([error] As String, code As Integer, Optional [from] As Integer = 0, Optional bits As Integer = 0) As String
Return to_string([set](to_array([error]), to_array(code), [from], bits))
End Function
Public Function [set]([error] As Byte(), code As String, Optional [from] As Integer = 0, Optional bits As Integer = 0) As Byte()
Return [set]([error], to_array(code), [from], bits)
End Function
Public Function [set]([error] As Byte(), code As Byte(), Optional [from] As Integer = 0, Optional bits As Integer = 0) As Byte()
Dim l As Integer
Dim m As Integer
Dim n As Integer
Dim results As New List(Of Byte)()
If bits <> 0 Then
[error] = reset([error], [from], bits)
m = [error].Length
End If
If [from] <> 0 Then
code = bitwise(code, [from])
n = code.Length
End If
l = If(m > n, m, n)
For i As Integer = 0 To l - 1
results.Add(CByte(
(If(i < m, [error](i), CByte(0))) Or
(If(i < n, code(i), CByte(0)))
))
Next
Return clean(results.ToArray())
End Function
Public Function [set]([error] As Byte(), code As Integer, Optional [from] As Integer = 0, Optional bits As Integer = 0) As Byte()
Return [set]([error], to_array(code), [from], bits)
End Function
Public Function [set]([error] As Integer, code As String, Optional [from] As Integer = 0, Optional bits As Integer = 0) As Integer
Return [set]([error], to_integer(code), [from], bits)
End Function
Public Function [set]([error] As Integer, code As Byte(), Optional [from] As Integer = 0, Optional bits As Integer = 0) As Integer
Return [set]([error], to_integer(code), [from], bits)
End Function
Public Function [set]([error] As Integer, code As Integer, Optional [from] As Integer = 0, Optional bits As Integer = 0) As Integer
If bits <> 0 Then [error] = reset([error], [from], bits)
If [from] <> 0 Then [error] = bitwise([error], [from])
Return [error] Or code
End Function
Public Shared Function get_keys(items As Object) As String()
Dim keys As New List(Of String)()
If TypeOf items Is String Then
If RE_KEY.IsMatch(DirectCast(items, String)) Then keys.Add(DirectCast(items, String))
ElseIf TypeOf items Is String() Then
For Each item As String In DirectCast(items, String())
If RE_KEY.IsMatch(item) AndAlso Not keys.Contains(item) Then keys.Add(item)
Next
ElseIf TypeOf items Is IEnumerable(Of Object) Then
For Each item As Object In DirectCast(items, IEnumerable(Of Object))
If item Is Nothing Then Continue For
If TypeOf item Is String Then
If RE_KEY.IsMatch(DirectCast(item, String)) AndAlso Not keys.Contains(DirectCast(item, String)) Then keys.Add(DirectCast(item, String))
Else
For Each key As String In get_keys(item)
If Not keys.Contains(key) Then keys.Add(key)
Next
End If
Next
End If
Return keys.ToArray()
End Function
Public Shared Function get_dictionaries(items As Object) As List(Of Dictionary(Of String, Object))
Dim dictionaries As New List(Of Dictionary(Of String, Object))()
If TypeOf items Is Dictionary(Of String, Object) Then
dictionaries.Add(DirectCast(items, Dictionary(Of String, Object)))
ElseIf TypeOf items Is IEnumerable(Of Object) Then
For Each item As Object In DirectCast(items, IEnumerable(Of Object))
dictionaries.AddRange(get_dictionaries(item))
Next
End If
Return dictionaries
End Function
Public Shared Function [get](Of T)(keys As Object, inputs As Object, Optional _default As T = Nothing) As T
Dim keys_list As String() = get_keys(keys)
If keys_list.Length <> 0 Then
For Each dictionary As Dictionary(Of String, Object) In get_dictionaries(inputs)
For Each key As String In keys_list
Dim value As Object = Nothing
If dictionary.TryGetValue(key, value) AndAlso TypeOf value Is T Then Return DirectCast(value, T)
Next
Next
End If
Return _default
End Function
Public Shared Function Unique(Of T)(items As IEnumerable(Of T)) As T()
Return items.Distinct().ToArray()
End Function
Public Shared Function is_array(value As Object) As Boolean
Return TypeOf value Is Array
End Function
Public Shared Function is_integer(value As Object) As Boolean
Return TypeOf value Is Integer
End Function
Public Shared Sub for_each_enumerate(Of T)(items As IEnumerable(Of T), action As Action(Of T, Integer))
Dim index As Integer = 0
For Each item As T In items
action(item, index)
index += 1
Next
End Sub
End Class
End Namespace