xxeell

Untitled

Jul 15th, 2018
94
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 24.09 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5.  
  6. namespace DarkBinaryLibrary
  7. {
  8.     public class BinaryType
  9.     {
  10.         private List<bool> content;
  11.  
  12.         private void add_bits(bool[] bits)
  13.         {
  14.             if (content == null) return;
  15.  
  16.             foreach (bool i in bits)
  17.             {
  18.                 content.Add(i);
  19.             }
  20.         }
  21.  
  22.         private bool[] byte_to_bits(byte b)
  23.         {
  24.             List<bool> res = new List<bool>();
  25.             bool t;
  26.  
  27.             for (int i = 1; i < byte.MaxValue; i *= 2)
  28.             {
  29.                 t = (b & i) == i;
  30.                 res.Add(t);
  31.             }
  32.  
  33.             res.Reverse();
  34.  
  35.             return res.ToArray();
  36.         }
  37.  
  38.         private byte bits_to_byte(bool[] bits)
  39.         {
  40.             if (bits.Length < 8)
  41.                 throw new Exception("В массиве недостаточно битов для создания байта");
  42.  
  43.             byte res = 0;
  44.             byte writer = 1;
  45.  
  46.             for (int i = 7; i >= 0; i--)
  47.             {
  48.                 if (bits[i]) res = (byte)(res | writer);
  49.                 writer *= 2;
  50.             }
  51.  
  52.             return res;
  53.         }
  54.  
  55.         private byte bits_to_byte(int index)
  56.         {
  57.             if (index < 0)
  58.                 throw new ArgumentOutOfRangeException("index");
  59.  
  60.             if (index >= content.Count)
  61.                 throw new ArgumentOutOfRangeException("index");
  62.  
  63.             if (index + 7 >= content.Count)
  64.                 throw new ArgumentOutOfRangeException("index", "Для указанного начального индекса недостаточно битов.");
  65.  
  66.             byte res = 0;
  67.             byte writer = 1;
  68.  
  69.             for (int i = 7; i >= 0; i--)
  70.             {
  71.                 if (content[index + i]) res = (byte)(res | writer);
  72.                 writer *= 2;
  73.             }
  74.  
  75.             return res;
  76.         }
  77.  
  78.         private int bits_to_int(int index)
  79.         {
  80.             if (index < 0)
  81.                 throw new ArgumentOutOfRangeException("index");
  82.  
  83.             if (index >= content.Count)
  84.                 throw new ArgumentOutOfRangeException("index");
  85.  
  86.             if (index + 31 >= content.Count)
  87.                 throw new ArgumentOutOfRangeException("index", "Для указанного начального индекса недостаточно битов.");
  88.  
  89.             int res = 0;
  90.             int writer = 1;
  91.  
  92.             for (int i = 31; i >= 0; i--)
  93.             {
  94.                 if (content[index + i]) res = (res | writer);
  95.                 writer *= 2;
  96.             }
  97.  
  98.             return res;
  99.         }
  100.  
  101.         private bool[] int_to_bits_with_bit_count(int n, byte bit_count)
  102.         {
  103.             if (bit_count < 1)
  104.                 throw new Exception("Слишком маленькое количество бит.");
  105.             if (bit_count > 32)
  106.                 throw new Exception("Слишком большое количество бит.");
  107.  
  108.             int max = 1;
  109.             for (byte i = 1; i <= bit_count; i++)
  110.             {
  111.                 max *= 2;
  112.             }
  113.  
  114.             if (n >= max)
  115.                 throw new Exception("Входное число больше максимального допустимого для этого количества бит.");
  116.  
  117.             List<bool> res = new List<bool>();
  118.             int reader = 1;
  119.  
  120.             for (byte i = 0; i < bit_count; i++)
  121.             {
  122.                 res.Add((n & reader) == reader);
  123.                 reader *= 2;
  124.             }
  125.  
  126.             res.Reverse();
  127.  
  128.             return res.ToArray();
  129.         }
  130.  
  131.         private bool[] byte_to_bits_with_bit_count(byte n, byte bit_count)
  132.         {
  133.             if (bit_count < 1)
  134.                 throw new Exception("Слишком маленькое количество бит.");
  135.             if (bit_count > 8)
  136.                 throw new Exception("Слишком большое количество бит.");
  137.  
  138.             int max = 1;
  139.             for (byte i = 1; i <= bit_count; i++)
  140.             {
  141.                 max *= 2;
  142.             }
  143.  
  144.             if (n >= max)
  145.                 throw new Exception("Входное число больше максимального допустимого для этого количества бит.");
  146.  
  147.             List<bool> res = new List<bool>();
  148.             byte reader = 1;
  149.  
  150.             for (byte i = 0; i < bit_count; i++)
  151.             {
  152.                 res.Add((n & reader) == reader);
  153.                 reader *= 2;
  154.             }
  155.  
  156.             res.Reverse();
  157.  
  158.             return res.ToArray();
  159.         }
  160.  
  161.         private byte bits_to_byte_with_bit_count(int index, byte bit_count)
  162.         {
  163.             if (index < 0)
  164.                 throw new ArgumentOutOfRangeException("index");
  165.  
  166.             if (index >= content.Count)
  167.                 throw new ArgumentOutOfRangeException("index");
  168.  
  169.             if (index + bit_count - 1 >= content.Count)
  170.                 throw new ArgumentOutOfRangeException("index", "Для указанного начального индекса недостаточно битов.");
  171.  
  172.             if (bit_count > 8)
  173.                 throw new ArgumentOutOfRangeException("bit_count", "В байте не может быть больше 8 бит.");
  174.  
  175.             if (bit_count < 1)
  176.                 throw new ArgumentOutOfRangeException("bit_count", "В байте не может быть меньше 1 бита.");
  177.  
  178.             byte res = 0;
  179.             byte writer = 1;
  180.  
  181.             for (int i = bit_count - 1; i >= 0; i--)
  182.             {
  183.                 if (content[index + i]) res = (byte)(res | writer);
  184.                 writer *= 2;
  185.             }
  186.  
  187.             return res;
  188.         }
  189.  
  190.         private int bits_to_int_with_bit_count(int index, byte bit_count)
  191.         {
  192.             if (index < 0)
  193.                 throw new ArgumentOutOfRangeException("index");
  194.  
  195.             if (index >= content.Count)
  196.                 throw new ArgumentOutOfRangeException("index");
  197.  
  198.             if (index + bit_count - 1 >= content.Count)
  199.                 throw new ArgumentOutOfRangeException("index", "Для указанного начального индекса недостаточно битов.");
  200.  
  201.             if (bit_count > 32)
  202.                 throw new ArgumentOutOfRangeException("bit_count", "В байте не может быть больше 32 бит.");
  203.  
  204.             if (bit_count < 1)
  205.                 throw new ArgumentOutOfRangeException("bit_count", "В байте не может быть меньше 1 бита.");
  206.  
  207.             int res = 0;
  208.             int writer = 1;
  209.  
  210.             for (int i = bit_count - 1; i >= 0; i--)
  211.             {
  212.                 if (content[index + i]) res = (res | writer);
  213.                 writer *= 2;
  214.             }
  215.  
  216.             return res;
  217.         }
  218.  
  219.         /// <summary>
  220.         /// Инициализация пустого экземпляра массива битов.
  221.         /// </summary>
  222.         public BinaryType()
  223.         {
  224.             content = new List<bool>();
  225.         }
  226.  
  227.         /// <summary>
  228.         /// Инициализация экземпляра массива битов с одним начальным битом.
  229.         /// </summary>
  230.         /// <param name="bit">Тот самый начальный бит.</param>
  231.         public BinaryType(bool bit)
  232.         {
  233.             content = new List<bool>();
  234.             content.Add(bit);
  235.         }
  236.  
  237.         /// <summary>
  238.         /// Инициализация экземпляра массива битов с несколькими начальными битами.
  239.         /// </summary>
  240.         /// <param name="bits">Массив начальных битов.</param>
  241.         public BinaryType(bool[] bits)
  242.         {
  243.             content = new List<bool>();
  244.             add_bits(bits);
  245.         }
  246.  
  247.         /// <summary>
  248.         /// Инициализация экземпляра массива битов из байта.
  249.         /// </summary>
  250.         /// <param name="b">Байт, преобразуемый в массив битов.</param>
  251.         public BinaryType(byte b)
  252.         {
  253.             content = new List<bool>();
  254.             bool[] bits = byte_to_bits(b);
  255.             add_bits(bits);
  256.         }
  257.  
  258.         /// <summary>
  259.         /// Инициализация экземпляра массива битов из массива байтов.
  260.         /// </summary>
  261.         /// <param name="bytes">Массив байтов, преобразуемый в массив битов.</param>
  262.         public BinaryType(byte[] bytes)
  263.         {
  264.             content = new List<bool>();
  265.             bool[] bits;
  266.  
  267.             foreach (byte i in bytes)
  268.             {
  269.                 bits = byte_to_bits(i);
  270.                 add_bits(bits);
  271.             }
  272.         }
  273.  
  274.         /// <summary>
  275.         /// Инициализация экземпляра массива битов из целого числа используя заданное количество бит.
  276.         /// </summary>
  277.         /// <param name="n">Число, преобразуемое в массив битов.</param>
  278.         /// <param name="bit_count">Количество используемых бит.</param>
  279.         public BinaryType(int n, byte bit_count)
  280.         {
  281.             if (bit_count > 32)
  282.                 throw new ArgumentOutOfRangeException("bit_count", "В байте не может быть больше 32 бит.");
  283.  
  284.             if (bit_count < 1)
  285.                 throw new ArgumentOutOfRangeException("bit_count", "В байте не может быть меньше 1 бита.");
  286.  
  287.             content = new List<bool>();
  288.             bool[] bits = int_to_bits_with_bit_count(n, bit_count);
  289.             add_bits(bits);
  290.         }
  291.  
  292.         /// <summary>
  293.         /// Инициализация экземпляра массива битов из байта используя заданное количество бит.
  294.         /// </summary>
  295.         /// <param name="n">Число, преобразуемое в массив битов.</param>
  296.         /// <param name="bit_count">Количество используемых бит.</param>
  297.         public BinaryType(byte n, byte bit_count)
  298.         {
  299.             if (bit_count > 8)
  300.                 throw new ArgumentOutOfRangeException("bit_count", "В байте не может быть больше 8 бит.");
  301.  
  302.             if (bit_count < 1)
  303.                 throw new ArgumentOutOfRangeException("bit_count", "В байте не может быть меньше 1 бита.");
  304.  
  305.             content = new List<bool>();
  306.             bool[] bits = byte_to_bits_with_bit_count(n, bit_count);
  307.             add_bits(bits);
  308.         }
  309.  
  310.         /// <summary>
  311.         /// Инициализация экземпляра массива битов из массива байтов
  312.         /// с указанным количеством битов на байт.
  313.         /// </summary>
  314.         /// <param name="bytes">Массив байтов, преобразуемый в массив битов.</param>
  315.         /// <param name="bit_count">Количество бит на 1 байт.</param>
  316.         public BinaryType(byte[] bytes, byte bit_count)
  317.         {
  318.             if (bit_count > 8)
  319.                 throw new ArgumentOutOfRangeException("bit_count", "В байте не может быть больше 8 бит.");
  320.  
  321.             if (bit_count < 1)
  322.                 throw new ArgumentOutOfRangeException("bit_count", "В байте не может быть меньше 1 бита.");
  323.  
  324.             content = new List<bool>();
  325.             bool[] bits;
  326.  
  327.             foreach (byte i in bytes)
  328.             {
  329.                 bits = byte_to_bits_with_bit_count(i, bit_count);
  330.                 add_bits(bits);
  331.             }
  332.         }
  333.  
  334.         /// <summary>
  335.         /// Возвращает массив битов в строковом представлении.
  336.         /// </summary>
  337.         /// <returns>Массив битов (0 и 1).</returns>
  338.         public override string ToString()
  339.         {
  340.             StringBuilder s = new StringBuilder();
  341.  
  342.             foreach (bool i in content)
  343.             {
  344.                 if (i) s.Append("1 ");
  345.                 else s.Append("0 ");
  346.             }
  347.  
  348.             return s.ToString();
  349.         }
  350.  
  351.         /// <summary>
  352.         /// Добавление бита.
  353.         /// </summary>
  354.         /// <param name="bit">Добавляемый бит.</param>
  355.         public void Add(bool bit)
  356.         {
  357.             content.Add(bit);
  358.         }
  359.  
  360.         /// <summary>
  361.         /// Добавление массива битов.
  362.         /// </summary>
  363.         /// <param name="bits">Добавляемый массив битов.</param>
  364.         public void Add(bool[] bits)
  365.         {
  366.             add_bits(bits);
  367.         }
  368.  
  369.         /// <summary>
  370.         /// Добавление байта (в виде битов).
  371.         /// </summary>
  372.         /// <param name="b">Добавляемый байт.</param>
  373.         public void Add(byte b)
  374.         {
  375.             bool[] bits = byte_to_bits(b);
  376.             add_bits(bits);
  377.         }
  378.  
  379.         /// <summary>
  380.         /// Добавление массива байтов (в виде битов).
  381.         /// </summary>
  382.         /// <param name="bytes">Добавляемый массив байтов.</param>
  383.         public void Add(byte[] bytes)
  384.         {
  385.             bool[] bits;
  386.  
  387.             foreach (byte i in bytes)
  388.             {
  389.                 bits = byte_to_bits(i);
  390.                 add_bits(bits);
  391.             }
  392.         }
  393.  
  394.         /// <summary>
  395.         /// Добавление массива битов из байта используя заданное количество бит.
  396.         /// </summary>
  397.         /// <param name="n">Число, преобразуемое в массив битов.</param>
  398.         /// <param name="bit_count">Количество используемых бит.</param>
  399.         public void Add(byte n, byte bit_count)
  400.         {
  401.             if (bit_count > 8)
  402.                 throw new ArgumentOutOfRangeException("bit_count", "В байте не может быть больше 8 бит.");
  403.  
  404.             if (bit_count < 1)
  405.                 throw new ArgumentOutOfRangeException("bit_count", "В байте не может быть меньше 1 бита.");
  406.  
  407.             bool[] bits = byte_to_bits_with_bit_count(n, bit_count);
  408.             add_bits(bits);
  409.         }
  410.  
  411.         /// <summary>
  412.         /// Добавление массива битов из массива байтов
  413.         /// с указанным количеством битов на байт.
  414.         /// </summary>
  415.         /// <param name="bytes">Массив байтов, преобразуемый в массив битов.</param>
  416.         /// <param name="bit_count">Количество бит на 1 байт.</param>
  417.         public void Add(byte[] bytes, byte bit_count)
  418.         {
  419.             if (bit_count > 8)
  420.                 throw new ArgumentOutOfRangeException("bit_count", "В байте не может быть больше 8 бит.");
  421.  
  422.             if (bit_count < 1)
  423.                 throw new ArgumentOutOfRangeException("bit_count", "В байте не может быть меньше 1 бита.");
  424.  
  425.             bool[] bits;
  426.  
  427.             foreach (byte i in bytes)
  428.             {
  429.                 bits = byte_to_bits_with_bit_count(i, bit_count);
  430.                 add_bits(bits);
  431.             }
  432.         }
  433.  
  434.         /// <summary>
  435.         /// Удаление последнего элемента.
  436.         /// </summary>
  437.         public void RemoveLast()
  438.         {
  439.             if (content.Count < 1)
  440.                 throw new Exception("Нечего удалять.");
  441.             content.RemoveAt(content.Count - 1);
  442.         }
  443.  
  444.         /// <summary>
  445.         /// Удаление элемента по указанному индексу.
  446.         /// </summary>
  447.         /// <param name="index">Индекс удаляемого файла.</param>
  448.         public void RemoveAt(int index)
  449.         {
  450.             if (index < 0)
  451.                 throw new ArgumentOutOfRangeException("index");
  452.  
  453.             if (index >= content.Count)
  454.                 throw new ArgumentOutOfRangeException("index", "Индекс находится вне границ массива.");
  455.             content.RemoveAt(content.Count - 1);
  456.         }
  457.  
  458.         /// <summary>
  459.         /// Удалить из массива некоторое количество бит, начиная с указанного адреса.
  460.         /// </summary>
  461.         /// <param name="index">Стартовый индекс.</param>
  462.         /// <param name="lenght">Количество удаляемых элементов.</param>
  463.         public void RemoveRange(int index, int lenght)
  464.         {
  465.             if (index < 0)
  466.                 throw new ArgumentOutOfRangeException("index");
  467.            
  468.             if (index >= content.Count)
  469.                 throw new ArgumentOutOfRangeException("index", "Индекс находится вне границ массива.");
  470.  
  471.             if (index + lenght >= content.Count)
  472.                 throw new Exception("Для указанных index и length элементы находятся вне границ массива.");
  473.  
  474.             content.RemoveRange(index, lenght);
  475.         }
  476.  
  477.         /// <summary>
  478.         /// Позволяет получить или задать значение массива битов по индексу.
  479.         /// </summary>
  480.         /// <param name="index">Индекс значения в массиве.</param>
  481.         public bool this[int index]
  482.         {
  483.             get
  484.             {
  485.                 if (index < 0)
  486.                     throw new ArgumentOutOfRangeException("index");
  487.  
  488.                 if (index >= content.Count)
  489.                     throw new ArgumentOutOfRangeException("index", "Индекс находится вне границ массива.");
  490.  
  491.                 return content[index];
  492.             }
  493.             set
  494.             {
  495.                 content[index] = value;
  496.             }
  497.         }
  498.  
  499.         /// <summary>
  500.         /// Получение массива битов.
  501.         /// </summary>
  502.         /// <returns>bool[]</returns>
  503.         public bool[] ToArray_bool()
  504.         {
  505.             return content.ToArray();
  506.         }
  507.  
  508.         /// <summary>
  509.         /// Перевод массива битов в массив байтов.
  510.         /// Если количество бит в массиве не будет кратным 8, то в начале автоматически будет добавлено нужное количество бит.
  511.         /// </summary>
  512.         /// <returns>byte[]</returns>
  513.         public byte[] ToArray_byte()
  514.         {
  515.             if (content.Count % 8 != 0)
  516.             {
  517.                 int q = content.Count % 8;
  518.                 for (int i = 0; i < q; i++)
  519.                 {
  520.                     content.Insert(0, false);
  521.                 }
  522.             }
  523.  
  524.             int length = content.Count / 8;
  525.  
  526.             byte[] res = new byte[length];
  527.  
  528.             for (int i = 0; i < length; i++)
  529.             {
  530.                 res[i] = bits_to_byte(i * 8);
  531.             }
  532.  
  533.             return res;
  534.         }
  535.  
  536.         /// <summary>
  537.         /// Перевод массива битов в массив байтов с указанным числом битов на байт.
  538.         /// Если количество бит в массиве не будет кратным указанному числу байт,
  539.         /// то в начале автоматически будет добавлено нужное количество бит.
  540.         /// </summary>
  541.         /// <param name="bit_count">Количество битов на байт.</param>
  542.         /// <returns>byte[]</returns>
  543.         public byte[] ToArray_byte(byte bit_count)
  544.         {
  545.             if (content.Count % bit_count != 0)
  546.             {
  547.                 int q = content.Count % bit_count;
  548.                 for (int i = 0; i < q; i++)
  549.                 {
  550.                     content.Insert(0, false);
  551.                 }
  552.             }
  553.  
  554.             int length = content.Count / bit_count;
  555.  
  556.             byte[] res = new byte[length];
  557.  
  558.             for (int i = 0; i < length; i++)
  559.             {
  560.                 res[i] = bits_to_byte_with_bit_count(i * bit_count, bit_count);
  561.             }
  562.  
  563.             return res;
  564.         }
  565.  
  566.         /// <summary>
  567.         /// Получение байта из 8 битов, начиная с указанного индекса.
  568.         /// </summary>
  569.         /// <param name="index">Начальный индекс.</param>
  570.         /// <returns></returns>
  571.         public byte GetByte(int index)
  572.         {
  573.             if (index < 0)
  574.                 throw new ArgumentOutOfRangeException("index");
  575.  
  576.             if (index >= content.Count)
  577.                 throw new ArgumentOutOfRangeException("index");
  578.  
  579.             if (index + 7 >= content.Count)
  580.                 throw new ArgumentOutOfRangeException("index", "Для указанного начального индекса недостаточно битов.");
  581.  
  582.             byte res = bits_to_byte(index);
  583.            
  584.             return res;
  585.         }
  586.  
  587.         /// <summary>
  588.         /// Возвращает байт с использованием заданного числа бит.
  589.         /// </summary>
  590.         /// <param name="index">Начальный индекс.</param>
  591.         /// <param name="bit_count">Число бит.</param>
  592.         /// <returns></returns>
  593.         public byte GetByte(int index, byte bit_count)
  594.         {
  595.             if (index < 0)
  596.                 throw new ArgumentOutOfRangeException("index");
  597.  
  598.             if (index >= content.Count)
  599.                 throw new ArgumentOutOfRangeException("index");
  600.  
  601.             if (index + bit_count - 1 >= content.Count)
  602.                 throw new ArgumentOutOfRangeException("index", "Для указанного начального индекса недостаточно битов.");
  603.  
  604.             byte res = bits_to_byte_with_bit_count(index, bit_count);
  605.             return res;
  606.         }
  607.  
  608.         /// <summary>
  609.         /// Получение целого числа из 32 битов, начиная с указанного индекса.
  610.         /// </summary>
  611.         /// <param name="index">Начальный индекс.</param>
  612.         /// <returns></returns>
  613.         public int GetInt32(int index)
  614.         {
  615.             if (index < 0)
  616.                 throw new ArgumentOutOfRangeException("index");
  617.  
  618.             if (index >= content.Count)
  619.                 throw new ArgumentOutOfRangeException("index");
  620.  
  621.             if (index + 31 >= content.Count)
  622.                 throw new ArgumentOutOfRangeException("index", "Для указанного начального индекса недостаточно битов.");
  623.  
  624.             int res = bits_to_int(index);
  625.  
  626.             return res;
  627.         }
  628.  
  629.         /// <summary>
  630.         /// Получение целого числа из указанного количества битов, начиная с указанного индекса.
  631.         /// </summary>
  632.         /// <param name="index">Начальный индекс.</param>
  633.         /// <returns></returns>
  634.         public int GetInt32(int index, byte bit_count)
  635.         {
  636.             if (index < 0)
  637.                 throw new ArgumentOutOfRangeException("index");
  638.  
  639.             if (index >= content.Count)
  640.                 throw new ArgumentOutOfRangeException("index");
  641.  
  642.             if (index + bit_count - 1 >= content.Count)
  643.                 throw new ArgumentOutOfRangeException("index", "Для указанного начального индекса недостаточно битов.");
  644.  
  645.             int res = bits_to_int_with_bit_count(index, bit_count);
  646.  
  647.             return res;
  648.         }
  649.     }
  650. }
Add Comment
Please, Sign In to add comment