SafeDispatch/LibrarySDR/Helpers/BinaryHexHelper.cs
2024-02-22 18:43:59 +02:00

260 lines
9.1 KiB
C#

using System;
using System.Collections;
using System.Linq;
using System.Text;
namespace LibrarySDR.Helpers
{
public class BinaryHexHelper
{
/// <summary>
/// Define ways of adding paddings to a hex string
/// </summary>
public enum Padding { LEFT, RIGHT };
public enum Endian { LITTLE, BIG };
public static Endian EndianType = Endian.LITTLE;
/// <summary>
/// Method that will convert a binary string to the corresponding hex string
/// by adding additional 0's in front of the binary number until a multiple of 8 is obtained
/// </summary>
/// <param name="binary">A binary number as a string</param>
/// <returns>String representing the hex value of the binary string</returns>
public static string BinaryStringToHexString(string binary)
{
return _BinaryStringToHexString(binary, Padding.LEFT);
}
/// <summary>
/// Method that will convert a binary string to the corresponding hex string
/// by adding additional 0's until a multiple of 8 is obtained
/// </summary>
/// <param name="binary">A binary number as a string</param>
/// <param name="padding">Padding option to which the additional 0's are added</param>
/// <returns>String representing the hex value of the binary string</returns>
public static string BinaryStringToHexString(string binary, Padding padding)
{
return _BinaryStringToHexString(binary, padding);
}
/// <summary>
/// Private method that will convert a binary string to the corresponding hex string
/// by adding additional 0's until a multiple of 8 is obtained
/// </summary>
/// <param name="binary">A binary number as a string</param>
/// <param name="padding">Padding option to which the additional 0's are added</param>
/// <returns>String representing the hex value of the binary string</returns>
private static string _BinaryStringToHexString(string binary, Padding padding)
{
StringBuilder result = new StringBuilder(binary.Length / 8 + 1);
// TODO: check all 1's or 0's... Will throw otherwise
int mod4Len = binary.Length % 8;
if (mod4Len != 0)
{
// pad to length multiple of 8 if required
if (padding == Padding.RIGHT)
binary = binary.PadRight(((binary.Length / 8) + 1) * 8, '0');
else if (padding == Padding.LEFT)
binary = binary.PadLeft(((binary.Length / 8) + 1) * 8, '0');
}
for (int i = 0; i < binary.Length; i += 8)
{
string eightBits = binary.Substring(i, 8);
result.AppendFormat("{0:X2}", Convert.ToByte(eightBits, 2));
}
return result.ToString().Trim();
}
public static String GetBits(string str, Encoding encoding)
{
byte[] data = encoding.GetBytes(str);
//storage for the resulting string
string result = string.Empty;
//iterate through the byte[]
foreach (byte value in data)
{
//storage for the individual byte
string binarybyte = Convert.ToString(value, 2);
//if the binarybyte is not 8 characters long, its not a proper result
while (binarybyte.Length < 8)
{
//prepend the value with a 0
binarybyte = "0" + binarybyte;
}
//append the binarybyte to the result
result += binarybyte;
}
//return the result
return result;
}
public static String LittleToBigEndianHexString(String littleEndianHexString)
{
StringBuilder sb = new StringBuilder("");
for (int i = 0; i < littleEndianHexString.Length / 2; i++)
sb.Append(littleEndianHexString.Substring((littleEndianHexString.Length / 2 - i - 1) * 2, 2));
return sb.ToString();
}
/// <summary>
/// Get corresponding bits as a string for the desired int value. The number of bits is specified
/// </summary>
/// <param name="value">Int value that needs to be transformed to binary string</param>
/// <param name="bitLength">Numer of bits that needs to be returned (the added ones will be 0)</param>
/// <returns>String represents the bits of an int value</returns>
public static String GetBits(Int64 value, int bitLength)
{
return _GetBits(value, bitLength, true);
}
/// <summary>
/// Get corresponding bits as a string for the desired int value. The number of bits is specified
/// </summary>
/// <param name="value">Int value that needs to be transformed to binary string</param>
/// <param name="bitLength">Numer of bits that needs to be returned</param>
/// <param name="isZeroPadded">Specify if the added bits should be 0 or 1</param>
/// <returns>String represents the bits of an int value</returns>
public static String GetBits(Int64 value, int bitLength, bool isZeroPadded)
{
return _GetBits(value, bitLength, isZeroPadded);
}
/// <summary>
/// Get corresponding bits as a string for the desired int value. The number of bits is specified
/// </summary>
/// <param name="value">Int value that needs to be transformed to binary string</param>
/// <param name="bitLength">Numer of bits that needs to be returned</param>
/// <param name="isZeroPadded">Specify if the added bits should be 0 or 1</param>
/// <returns>String represents the bits of an int value</returns>
private static string _GetBits(Int64 value, int bitLength, bool isZeroPadded)
{
String result = Convert.ToString(value, 2).PadLeft(bitLength, isZeroPadded ? '0' : '1');
// revers bytes if little endian
if(EndianType == Endian.LITTLE)
{
StringBuilder sb = new StringBuilder("");
for (int i = 0; i < result.Length / 8; i++)
sb.Append(result.Substring((result.Length / 8 - i - 1) * 8, 8));
result = sb.ToString();
}
/*
byte[] arrayResponse = BitConverter.GetBytes(value);
// if system is in BigEndian and the required is for little
if ((!BitConverter.IsLittleEndian && EndianType == Endian.LITTLE)
|| (BitConverter.IsLittleEndian && EndianType == Endian.BIG))
Array.Reverse(arrayResponse);
return BitConverter.ToString(arrayResponse);
*/
return result;
}
public static byte[] StringToByteArray(string hex)
{
return Enumerable.Range(0, hex.Length)
.Where(x => x % 2 == 0)
.Select(x => Convert.ToByte(hex.Substring(x, 2), 16))
.ToArray();
}
public static byte[] StringToByteArrayFastest(string hex)
{
if (hex.Length % 2 == 1)
throw new Exception("The binary key cannot have an odd number of digits");
byte[] arr = new byte[hex.Length >> 1];
for (int i = 0; i < hex.Length >> 1; ++i)
{
arr[i] = (byte)((GetHexVal(hex[i << 1]) << 4) + (GetHexVal(hex[(i << 1) + 1])));
}
return arr;
}
private static int GetHexVal(char hex)
{
int val = (int)hex;
//For uppercase A-F letters:
return val - (val < 58 ? 48 : 55);
//For lowercase a-f letters:
//return val - (val < 58 ? 48 : 87);
//Or the two combined, but a bit slower:
//return val - (val < 58 ? 48 : (val < 97 ? 55 : 87));
}
public static string GetEscapeSequence(char c)
{
//return "\\u" +
return ((int)c).ToString("X4");
}
public static string ToBitString(BitArray bits, Endian endian)
{
if (endian == Endian.LITTLE)
{
var sb = new StringBuilder();
for (int i = 0; i < bits.Count; i++)
{
char c = bits[i] ? '1' : '0';
sb.Append(c);
}
return sb.ToString();
}
else
{
var sb = new StringBuilder();
for (int i = bits.Count / 2 - 1; i >= 0; i--)
{
char c = bits[i] ? '1' : '0';
sb.Append(c);
}
for (int i = bits.Count - 1; i >= bits.Count /2; i--)
{
char c = bits[i] ? '1' : '0';
sb.Append(c);
}
return sb.ToString();
}
}
}
}