diff --git a/CSharp/ErrorsManager.cs b/CSharp/ErrorsManager.cs new file mode 100644 index 0000000..c783236 --- /dev/null +++ b/CSharp/ErrorsManager.cs @@ -0,0 +1,444 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Mail; +using System.Text.RegularExpressions; + +namespace ErrorsManager{ + + // public abstract record Error{ + + // private Error(){} + + // public sealed record String(string value):Error; + // public sealed record Array(byte[] value):Error; + // public sealed record Integer(int value):Error; + + // } + + class ErrorsManager{ + + public static readonly char[] ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".ToCharArray(); + + public static readonly Regex RE_KEY = new Regex(@"^[a-z_][a-z0-9_]*$", RegexOptions.IgnoreCase | RegexOptions.Compiled); + + private Error error = 0; + private char[] alphabet; + private Dictionary dictionary = new Dictionary(); + private byte _base; + private byte power; + + public ErrorsManager(object? inputs = null){ + + set_alphabet(get("alphabet", inputs, ALPHABET)); + + } + + public int set_alphabet(object? alphabet = null){ + + int original_length; + + error = 0; + + if(alphabet == null) + this.alphabet = ALPHABET; + else if(alphabet is string alphabet_string) + this.alphabet = alphabet_string.ToCharArray(); + else if(alphabet is IEnumerable alphabet_enumerable) + this.alphabet = alphabet_enumerable.ToArray(); + else{ + error |= 1 << 2; + this.alphabet = ALPHABET; + } + + original_length = this.alphabet.Length; + + this.alphabet = this.alphabet.Distinct().ToArray(); + + if(this.alphabet.Length < 2){ + error |= 1 << 3; + this.alphabet = ALPHABET; + } + if(this.alphabet.Length != original_length) + error |= 1 << 4; + if(this.alphabet.Length > 128) + error |= 1 << 5; + + this.alphabet = this.alphabet.Take( + _base = (byte)Math.Pow(2, + power = (byte)Math.Log2(this.alphabet.Length) + ) + ).ToArray(); + + dictionary.Clear(); + for(byte i = 0; i < this.alphabet.Length; i ++) + dictionary[this.alphabet[i]] = i; + + return error; + } + + public string get_alphabet(){ + return new string(alphabet); + } + + public byte[] to_array(object code){ + if(code is string _string) + return _string.Select(character => dictionary[character]).ToArray(); + if(code is byte[] array) + return array; + if(code is int integer){ + + List hexas = new List(); + + while(integer != 0){ + hexas.Add((byte)(integer % _base)); + integer /= _base; + } + + return hexas.ToArray(); + } + return new byte[]{}; + } + + public string to_string(object code){ + if(code is string _string) + return _string; + if(code is byte[] array) + return new string(array.Select(value => alphabet[value]).ToArray()); + if(code is int integer){ + + string hexas = new string(); + + while(integer != 0){ + hexas += alphabet[(byte)(integer % _base)]; + integer /= _base; + } + + return hexas; + } + return ""; + } + + public int to_integer(object code){ + if(code is string _string){ + + int integer = 0; + + for(byte i = 0; i < _string.Length; i ++) + integer = integer * _base + dictionary[_string[i]]; + + return integer; + } + if(code is byte[] array){ + + int integer = 0; + + for(byte i = 0; i < array.Length; i ++) + integer = integer * _base + array[i]; + + return integer; + } + if(code is int integer) + return integer; + return 0; + } + + public (int, string)[] process(Error code, IEnumerable messages){ + + List<(int, string)> response = new List<(int, string)>(); + + for_each_enumerate(get_hexas_from(code), (hexa, i) => { + for(byte j = 0; j < power && (hexa & 1 << j) <= hexa; j ++) + if((hexa & 1 << j) != 0){ + + int x = i * power + j; + + response.Add((x, messages.ElementAtOrDefault(x) ?? "error_message_" + x.ToString())); + + } + }); + + return response.ToArray(); + } + + public int get_bits(object code){ + if(code is string _string) + return _string.Length == 0 ? 0 : (_string.Length - 1) * power + (int)Math.Ceiling(Math.Log2(dictionary[_string.Last()] + 1)); + if(code is byte[] array) + return array.Length == 0 ? 0 : (array.Length - 1) * power + (int)Math.Ceiling(Math.Log2(array.Last() + 1)); + if(code is int integer) + return (int)Math.Ceiling(Math.Log2(integer + 1)); + return 0; + } + + public T bitwise(T code, int bits){ + if(code is string _string) + return (T)(object)to_string(bitwise(to_array(_string), bits)); + if(code is byte[] array){ + + byte shift; + int mask; + List hexas; + + if(bits < 0){ + if(array.Length < (int)((bits *= -1) / power)) + return (T)(object)new byte[]{0}; + + shift = (byte)(bits % power); + mask = _base - 1; + hexas = array.ToList(); + + hexas.RemoveRange(0, (int)(bits / power)); + + if(shift != 0 && hexas.Count != 0){ + + int l = hexas.Count - 1; + + for(int i = 0; i < l; i ++) + hexas[i] = (byte)((hexas[i] >> shift) | ((hexas[i + 1] << (power - shift)) & mask)); + hexas[hexas.Count - 1] >>= shift; + + } + + return (T)(object)hexas.ToArray(); + }; + if(bits > 0){ + + shift = (byte)(bits % power); + mask = _base - 1; + hexas = array.ToList(); + + if(shift != 0){ + + int last_hexa = hexas[hexas.Count - 1] << shift; + + for(int i = hexas.Count - 1; i > 0; i --) + hexas[i] = (byte)((hexas[i] << shift) | ((hexas[i - 1] >> (power - shift)) & mask)); + hexas[0] = (byte)((hexas[0] << shift) & mask); + + if(last_hexa >= _base) + hexas.Add((byte)(last_hexa >> power)); + + } + for(int i = bits / power; i > 0; i --) + hexas.Insert(0, 0); + + return (T)(object)hexas.ToArray(); + } + return (T)(object)array; + } + if(code is int integer) + return (T)(object)( + bits > 0 ? integer << bits : + bits < 0 ? integer >> -bits : + integer); + return code; + } + + public void get_from_bits(object code, ref int from, ref int bits){ + if(from < 0){ + from = get_bits(code) + from; + if(from < 0) + from = 0; + } + if(bits < 0){ + from += bits; + bits *= -1; + if(from < 0){ + bits += from; + from = 0; + } + } + } + + public T reset(T code, int from, int bits = 0, bool reversed = false){ + if(bits == 0 || (from == 0 && bits < 0)) + return code; + if(code is string _string) + return (T)(object)to_string(reset(to_array(_string), from, bits, reversed)); + if(code is byte[] array){ + + List hexas = array.ToList(); + int hexa_from; + int hexa_to; + int l; + byte from_mask; + byte to_mask; + + get_from_bits(array, ref from, ref bits); + hexa_from = (int)(from / power); + hexa_to = (int)((from + bits) / power); + + if(reversed){ + + l = from % power; + from_mask = (byte)(~-(1 << power - l) << l); + to_mask = (byte)~-(1 << (from + bits) % power); + + for(int i = 0; i < hexas.Count; i ++) + if(i < hexa_from || i > hexa_to) + hexas[i] = 0; + + if(hexa_from == hexa_to) + hexas[hexa_to] &= (byte)(from_mask & to_mask); + else{ + hexas[hexa_from] &= from_mask; + if(hexa_to < hexas.Count) + hexas[hexa_to] &= to_mask; + } + + }else{ + + l = (from + bits) % power; + from_mask = (byte)~-(1 << (from % power)); + to_mask = (byte)(~-(1 << power - l) << l); + + if(hexa_from == hexa_to){ + hexas[hexa_to] &= (byte)(from_mask | to_mask); + }else{ + hexas[hexa_from] &= from_mask; + for(int i = hexa_from + 1; i < hexa_to && i < hexas.Count; i ++) + hexas[i] = 0; + if(hexa_to < hexas.Count) + hexas[hexa_to] &= to_mask; + } + } + + return (T)(object)hexas.ToArray(); + } + if(code is int integer){ + + get_from_bits(integer, ref from, ref bits); + + return (T)(object)(integer & (reversed ? + ~-(1 << bits) << from : + (~-(1 << get_bits(integer)) << from + bits) | ~-(1 << from))); + } + return code; + } + + public T get_range(T code, int from, int length = 0){ + if(code is string _string) + return to_string(get_range(to_array(_string), length)); + if(code is byte[] array){ + + List hexas = new List(); + + if(from > 0){ + + byte shift = (byte)(from % power); + int mask = ~-_base; + + hexas.AddRange(array.Take(from / power)); + if(shift != 0){ + for(int i = hexas.Count - 2; i >= 0; i --) + hexas[i] = (byte)((hexas[i] >> shift) | ((hexas[i + 1] << (power - shift)) & mask)); + hexas[hexas.Count - 1] = (byte)(hexas.Last() >> shift); + } + + } + if(length > 0){ + + byte shift = (byte)(length % power); + + hexas.Take((int)Math.Ceiling(hexas.Count / (double)power)); + if(shift != 0) + hexas[hexas.Count - 1] = (byte)(hexas.Last() & ~-(1 << shift)); + } + + return to_integer(array.Skip(from / power).Take((int)Math.Ceiling((length != 0 ? length : get_bits(array) - from) / (double)power)).ToArray()); + } + if(code is int integer) + return (from > 0 ? integer >> from : integer) & (length > 0 ? ~(-1 << length) : integer); + return code; + } + + public bool has(Error code, int? bits = null){ + return code switch{ + Error.String _string => _string.value.ToList().Take(get_hexas_from_bits(bits)).Length * power > bits, + Error.Array array => array.value.ToList().Take(Math.Ceiling(Math.Log2(bits))).Where(hexa => hexa != 0).Count() != 0, + Error.Integer integer => (bits != null && bits != 0 ? ~-(1 << bits) & integer.value : integer.value) != 0, + _ => false + }; + } + + public static List get_keys(object? items){ + + List keys = new List(); + + if(items is string item_string){ + if(RE_KEY.IsMatch(item_string)) + keys.Add(item_string); + }else if(items is IEnumerable strings){ + foreach(string item_i in strings) + if(!keys.Contains(item_i) && RE_KEY.IsMatch(item_i)) + keys.Add(item_i); + }else if(items is IEnumerable list) + foreach(object? item in list){ + if(item == null) + continue; + if(item is string string_item){ + if(!keys.Contains(string_item) && RE_KEY.IsMatch(string_item)) + keys.Add(string_item); + }else + foreach(string key in get_keys(item)) + if(!keys.Contains(key) && RE_KEY.IsMatch(key)) + keys.Add(key); + } + + return keys; + } + + public static List> get_dictionaries(object? items){ + + List> dictionaries = new List>(); + + if(items is Dictionary dictionary) + dictionaries.Add(dictionary); + else if(items is IEnumerable list) + foreach(object? item in list) + dictionaries.AddRange(get_dictionaries(item)); + + return dictionaries; + } + + public static T? get(object keys, object? dictionaries, T? _default = default(T?)){ + + List keys_list = get_keys(keys); + + if(keys_list.Count != 0) + foreach(Dictionary dictionary in get_dictionaries(dictionaries)) + foreach(string key in keys_list) + if(dictionary.TryGetValue(key, out object? value) && value is T typed) + return typed; + return _default; + } + + public static T[] unique(IEnumerable items){ + return items.Distinct().ToArray(); + } + + public static bool is_string(object value){ + return value is string; + } + + public static bool is_array(object value){ + return value is byte[]; + } + + public static bool is_integer(object value){ + return value is int; + } + + public static void for_each_enumerate(IEnumerable items, Action action){ + + int i = 0; + + foreach(T item in items) + action(item, i ++); + + } + + } + +} \ No newline at end of file diff --git a/CSharp/ErrorsManager.csproj b/CSharp/ErrorsManager.csproj new file mode 100755 index 0000000..41964d3 --- /dev/null +++ b/CSharp/ErrorsManager.csproj @@ -0,0 +1,23 @@ + + + Exe + net10.0;net462 + enable + enable + latest + AnP + AnP + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + \ No newline at end of file diff --git a/CSharp/Program.cs b/CSharp/Program.cs new file mode 100755 index 0000000..777ff2d --- /dev/null +++ b/CSharp/Program.cs @@ -0,0 +1,13 @@ +using System; + +namespace ErrorsManager{ + class Program{ + + static void Main(string[] args){ + + Console.WriteLine("Hello World!"); + + } + + } +} \ No newline at end of file diff --git a/Python/v2/ErrorsManager.py b/Python/v2/ErrorsManager.py index 2fd640b..7e3cc16 100644 --- a/Python/v2/ErrorsManager.py +++ b/Python/v2/ErrorsManager.py @@ -19,7 +19,7 @@ class ErrorsManager: self.__alphabet:tuple[str] = ( tuple(alphabet) if isinstance(alphabet, (list, str)) else alphabet) - self.__alphabet_dictionary:dict[str, int] = {character : i for i, character in enumerate(self.__alphabet)} + self.__alphabet_map:dict[str, int] = {character : i for i, character in enumerate(self.__alphabet)} self.__base:int = self.get_value("base", inputs, maximum_base) self.__mask:int @@ -52,7 +52,7 @@ class ErrorsManager: hexa:str for i, hexa in enumerate(reversed(code)): - integer |= self.__alphabet_dictionary[hexa] << self.__base * i + integer |= self.__alphabet_map[hexa] << self.__base * i return integer if isinstance(code, (list, tuple)): @@ -70,7 +70,7 @@ class ErrorsManager: def to_array(self:Self, code:str|int|Sequence[int]) -> list[int]: if isinstance(code, str): - return [self.__alphabet_dictionary[hexa] for hexa in code] + return [self.__alphabet_map[hexa] for hexa in code] if isinstance(code, list): return list(code) if isinstance(code, tuple): @@ -86,10 +86,10 @@ class ErrorsManager: return list(reversed(array)) return [] - def reset(self:Self, code:int, start:int, length:int) -> int: + def reset_bak(self:Self, code:int, start:int, length:int) -> int: return code and (code & ~(~-(1 << length) << start)) - def set(self:Self, code:int, map:Sequence[int], codes:Sequence[int], start:int = 0, clean_bits:int = 0) -> int: + def set_bak(self:Self, code:int, map:Sequence[int], codes:Sequence[int], start:int = 0, clean_bits:int = 0) -> int: new_code:int = 0 shift:int = 0 @@ -105,10 +105,71 @@ class ErrorsManager: return ( (code & ~-(1 << start)) | (new_code << start) | - # ((code >> start + shift) << start + shift) (code & ~(~-(1 << start + shift))) ) + def has(self:Self, code:str) -> bool: + + errors:tuple[str] = self.__alphabet[1:] + character:str + + for character in code: + if character in errors: + return True + return False + + def clean(self:Self, code:str) -> str: + + while code[0] == self.__alphabet[0]: + code = code[1:] + + return code + + def reset(self:Self, code:str, start:int = 0, length:int = 0) -> str: + + i:int + character:str + total:int = start + (length or (length := len(code) * self.__base)) + _from:int|None = -start // self.__base or None + _to:int|None = (-total // self.__base) - (1 if total % self.__base else 0) or None + hexas:list[int] = [] + + if _from: + start += _from * self.__base + total += _from * self.__base + + for i, character in enumerate(reversed(code[-_to:_from])): + + bit:int = i * self.__base + next_bit:int = bit + self.__base + + if bit >= start and next_bit < total: + hexas.append(0) + continue + + hexa:int = self.__alphabet_map[character] + j:int + + for j in range(self.__base): + if bit < start: + continue + if bit >= total: + break + hexa &= ~(1 << j) + bit += 1 + + return ( + (code[:_to] if _to else "") + + "".join(self.__alphabet[hexa] for hexa in hexas)[::-1] + + (code[_from:] if _from else "") + ) + + def set(self:Self, code:str, new_code:int|str, start:int = 0, clean_bits:int = 0) -> str: + + + + return code + def validate(self:Self, code:int, map:Sequence[int],