603 lines
20 KiB
C#
603 lines
20 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Text.RegularExpressions;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace XYLEM.Base
|
|
{
|
|
public static class NumberConvert
|
|
{
|
|
public static readonly string ColumnSeperatorCSV = ((2.3).ToString().Contains(".") ? "," : ";");
|
|
private static readonly int base10 = 10;
|
|
private static readonly char[] cHexa = new char[] { 'A', 'B', 'C', 'D', 'E', 'F' };
|
|
private static readonly int[] iHexaNumeric = new int[] { 10, 11, 12, 13, 14, 15 };
|
|
private static readonly int[] iHexaIndices = new int[] { 0, 1, 2, 3, 4, 5 };
|
|
private static readonly int asciiDiff = 48;
|
|
|
|
public static string PadLeft(this String text, int minLength)
|
|
{
|
|
int iCount = minLength - text.Length;
|
|
String textRet = "";
|
|
if (iCount > 0)
|
|
{
|
|
textRet = new String('0', iCount);
|
|
}
|
|
return textRet + text;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Tag for values input is done as "decimal" and is placed ex. in front or behinde the value that needs to be converted
|
|
/// </summary>
|
|
public static readonly string ValueInputAsDecimalTag = "decimal";
|
|
|
|
/// <summary>
|
|
/// Tag for values input is done as "binary" and is placed ex. in front or behinde the value that needs to be converted
|
|
/// </summary>
|
|
public static readonly string ValueInputAsBinaryTag = "binary";
|
|
|
|
|
|
/// <summary>
|
|
/// Tag for values input is done as "octal" and is placed ex. in front or behinde the value that needs to be converted
|
|
/// </summary>
|
|
public static readonly string ValueInputAsOctalEndTag = "octal";
|
|
|
|
/// <summary>
|
|
/// Tag for values input is done as "0o" and is placed ex. in front the value that needs to be converted
|
|
/// </summary>
|
|
public static readonly string ValueInputAsOctalFrontTag = "0o";
|
|
|
|
/// <summary>
|
|
/// Tag for values input is done as "hex" and is placed ex. in front or behinde the value that needs to be converted
|
|
/// </summary>
|
|
public static readonly string ValueInputAsHexEndTag = "hex";
|
|
|
|
/// <summary>
|
|
/// Tag for values input is done as "0x" and is placed ex. in front the value that needs to be converted
|
|
/// </summary>
|
|
public static readonly string ValueInputAsHexFrontTag = "0x";
|
|
|
|
|
|
/// <summary>
|
|
/// Tag for values input is done as "bin" and is placed ex. in front or behinde the value that needs to be converted
|
|
/// </summary>
|
|
public static readonly string ValueInputAsBinaryEndTag = "bin";
|
|
|
|
/// <summary>
|
|
/// Tag for values input is done as "0b" and is placed ex. in front the value that needs to be converted
|
|
/// </summary>
|
|
public static readonly string ValueInputAsBinaryFrontTag = "0b";
|
|
|
|
/// <summary>
|
|
/// Convert byte values as in a string byte array
|
|
/// </summary>
|
|
/// <param name="byteValues"> must be like "0x12, 0x12, 0x12" or "1010bin; 1010bin; 1010bin" or "decimal 123, 123, 123"</param>
|
|
/// <returns></returns>
|
|
public static byte[] ValuesToBytes(this string byteValues)
|
|
{
|
|
try
|
|
{
|
|
List<byte> ret = new List<byte>();
|
|
var isHexadecimal = false;
|
|
var isDecimal = false;
|
|
var isBinary = false;
|
|
byteValues = byteValues.Trim().ToLower();
|
|
bool isBinaryMatch = (new Regex(@"^[01 ]+$")).IsMatch(byteValues);
|
|
bool isHexMatch = (new Regex(@"^[0-9a-f ]+$")).IsMatch(byteValues);
|
|
if (!string.IsNullOrEmpty(byteValues) && (byteValues.Contains(ValueInputAsHexEndTag) || byteValues.Contains("0x") || (isHexMatch && !isBinaryMatch)))
|
|
{
|
|
byteValues = byteValues.ToLower().Replace(ValueInputAsHexEndTag, "");
|
|
isHexadecimal = true;
|
|
}
|
|
else if (!string.IsNullOrEmpty(byteValues) && (byteValues.Contains(ValueInputAsDecimalTag) || isBinaryMatch))
|
|
{
|
|
byteValues = byteValues.Replace(ValueInputAsDecimalTag, "");
|
|
isDecimal = true;
|
|
}
|
|
else if (!string.IsNullOrEmpty(byteValues) && byteValues.Contains(ValueInputAsBinaryTag))
|
|
{
|
|
byteValues = byteValues.Replace(ValueInputAsBinaryTag, "");
|
|
isBinary = true;
|
|
}
|
|
var chunks = byteValues.Trim(new char[] { ' ' }).Split(new string[] { ",", ";", " ", Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
|
|
foreach (var value in chunks)
|
|
{
|
|
var toConvert = value.Trim();
|
|
if (!string.IsNullOrEmpty(toConvert))
|
|
{
|
|
if (isHexadecimal || !isBinary && !isDecimal && (toConvert.StartsWith(ValueInputAsHexFrontTag) || toConvert.ToLower().Contains(ValueInputAsHexEndTag)))
|
|
{
|
|
ret.Add(Convert.ToByte(toConvert.Replace(ValueInputAsHexFrontTag, "").ToLower().Replace(ValueInputAsHexEndTag, ""), 16));
|
|
}
|
|
else if (isBinary || !isDecimal && (toConvert.StartsWith(ValueInputAsBinaryFrontTag) || toConvert.ToLower().Contains(ValueInputAsBinaryEndTag)))
|
|
{
|
|
ret.Add(Convert.ToByte(toConvert.Replace(ValueInputAsBinaryFrontTag, "").ToLower().Replace(ValueInputAsBinaryEndTag, ""), 2));
|
|
}
|
|
else
|
|
{
|
|
ret.Add(Convert.ToByte(toConvert, 10));
|
|
}
|
|
}
|
|
}
|
|
return ret.ToArray();
|
|
}
|
|
catch
|
|
{
|
|
return null; // Error
|
|
}
|
|
}
|
|
|
|
public static string UnsignedHexToDecimal(this string Hex)
|
|
{
|
|
try
|
|
{
|
|
return Convert.ToUInt64(Hex, 16).ToString();
|
|
}
|
|
catch
|
|
{
|
|
return "?";
|
|
}
|
|
}
|
|
|
|
public static string UnsignedDecimalToHex(this string iDec, int padLeft, bool Add_0x)
|
|
{
|
|
try
|
|
{
|
|
return UnsignedDecimalToHex(Convert.ToUInt64(iDec), padLeft, Add_0x);
|
|
}
|
|
catch
|
|
{
|
|
return "?";
|
|
}
|
|
}
|
|
|
|
public static string UnsignedDecimalToHex(this UInt32 iDec, int padLeft, bool Add_0x)
|
|
{
|
|
try
|
|
{
|
|
return ((Add_0x) ? ValueInputAsHexFrontTag : "") + String.Format("{0:X}", iDec).PadLeft(padLeft, '0');
|
|
}
|
|
catch
|
|
{
|
|
return "?";
|
|
}
|
|
}
|
|
|
|
public static string DecimalToHex(this Int32 iDec, int padLeft, bool Add_0x)
|
|
{
|
|
try
|
|
{
|
|
return ((Add_0x) ? ValueInputAsHexFrontTag : "") + String.Format("{0:X}", iDec).PadLeft(padLeft, '0');
|
|
}
|
|
catch
|
|
{
|
|
return "?";
|
|
}
|
|
}
|
|
|
|
public static string UnsignedDecimalToHex(this UInt64 iDec, int padLeft, bool Add_0x)
|
|
{
|
|
try
|
|
{
|
|
return ((Add_0x) ? ValueInputAsHexFrontTag : "") + String.Format("{0:X}", iDec).PadLeft(padLeft, '0');
|
|
}
|
|
catch
|
|
{
|
|
return "?";
|
|
}
|
|
}
|
|
|
|
public static string DecimalToHex(this Int64 iDec, int padLeft, bool Add_0x)
|
|
{
|
|
try
|
|
{
|
|
return ((Add_0x) ? ValueInputAsHexFrontTag : "") + String.Format("{0:X}", iDec).PadLeft(padLeft, '0');
|
|
}
|
|
catch
|
|
{
|
|
return "?";
|
|
}
|
|
}
|
|
|
|
public static string UnsignedDecimalToBin(this string dec, bool Add_0b)
|
|
{
|
|
try
|
|
{
|
|
return ((Add_0b) ? ValueInputAsBinaryFrontTag : "") + UnsignedDecimalToBase(Convert.ToUInt64(dec), 2);
|
|
}
|
|
catch
|
|
{
|
|
return "?";
|
|
}
|
|
}
|
|
|
|
static string DoAutoPadLeft(this string valueAsStr)
|
|
{
|
|
var numberToPad = (valueAsStr.Length <= 8) ? 8 : (valueAsStr.Length <= 16) ? 16 : (valueAsStr.Length <= 32) ? 32 : 64;
|
|
return valueAsStr.PadLeft(numberToPad, '0');
|
|
}
|
|
|
|
static string DoAutoSpcaePadEvery4Char(this string ValueAsStr)
|
|
{
|
|
if (String.IsNullOrEmpty(ValueAsStr))
|
|
{
|
|
return ValueAsStr;
|
|
}
|
|
else
|
|
{
|
|
ValueAsStr = ValueAsStr.Trim();
|
|
var MissingChar = ValueAsStr.Length % 4;
|
|
ValueAsStr = ValueAsStr.PadLeft(ValueAsStr.Length + 4 - MissingChar, '0');
|
|
return Regex.Replace(ValueAsStr.Trim(), @"(.{4})", "$1 ").Trim();
|
|
}
|
|
}
|
|
|
|
public static string ToUnsignedBin(this int value, bool Add_0b)
|
|
{
|
|
try
|
|
{
|
|
return ((Add_0b) ? ValueInputAsBinaryFrontTag : "") + UnsignedDecimalToBase((UInt32)value, 2).DoAutoPadLeft();
|
|
}
|
|
catch
|
|
{
|
|
return "?";
|
|
}
|
|
}
|
|
|
|
public static string ToUnsignedBin(this uint value, bool Add_0b)
|
|
{
|
|
try
|
|
{
|
|
return ((Add_0b) ? ValueInputAsBinaryFrontTag : "") + UnsignedDecimalToBase(value, 2).DoAutoPadLeft();
|
|
}
|
|
catch
|
|
{
|
|
return "?";
|
|
}
|
|
}
|
|
|
|
public static string ToUnsignedBin(this Int64 value)
|
|
{
|
|
try
|
|
{
|
|
return UnsignedDecimalToBase((UInt32)value, 2).DoAutoPadLeft();
|
|
}
|
|
catch
|
|
{
|
|
return "?";
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// To string like 0bxxxxxxx depending of selection
|
|
/// </summary>
|
|
/// <param name="value">what value to show</param>
|
|
/// <param name="Add_0b">add 0b in front to indicate it is binary</param>
|
|
/// <param name="DoAutoPadLeft">"true" if pad left front with all 0 for the actual value type else "false" only pad with up to 4 bits 0 to easy read</param>
|
|
/// <returns></returns>
|
|
public static string ToUnsignedBin(this UInt64 value, bool Add_0b, bool DoAutoPadLeft = true)
|
|
{
|
|
try
|
|
{
|
|
var ret = UnsignedDecimalToBase(value, 2);
|
|
if (ret.Length == 0)
|
|
{
|
|
ret += "0"; // Always show 0 if no 1 is set
|
|
}
|
|
if (DoAutoPadLeft)
|
|
{
|
|
ret = ret.DoAutoPadLeft();
|
|
}
|
|
else
|
|
{
|
|
ret = ret.DoAutoSpcaePadEvery4Char();
|
|
}
|
|
return ((Add_0b) ? ValueInputAsBinaryFrontTag : "") + ret;
|
|
}
|
|
catch
|
|
{
|
|
return "?";
|
|
}
|
|
}
|
|
|
|
public static string ToBin(this byte value, bool Add_0b)
|
|
{
|
|
try
|
|
{
|
|
return ((Add_0b) ? ValueInputAsBinaryFrontTag : "") + UnsignedDecimalToBase(value, 2).DoAutoPadLeft();
|
|
}
|
|
catch
|
|
{
|
|
return "?";
|
|
}
|
|
}
|
|
|
|
public static string ToDec(this byte value)
|
|
{
|
|
return value.ToString("D3");
|
|
}
|
|
|
|
public static string ToHex(this byte value, bool Add_0x)
|
|
{
|
|
return DecimalToHex(value, 2, Add_0x);
|
|
}
|
|
|
|
public static string ToHex(this byte[] values, bool Add_0x, bool seperatorForCSV)
|
|
{
|
|
if (values == null) { return "Array is empty!"; }
|
|
string ret = "";
|
|
foreach (var value in values)
|
|
{
|
|
ret += (!String.IsNullOrEmpty(ret) ? (seperatorForCSV ? ColumnSeperatorCSV + " " : ", ") : "") + value.ToHex(Add_0x);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
public static string ToDec(this byte[] values)
|
|
{
|
|
if (values == null) { return "Array is empty!"; }
|
|
string ret = "";
|
|
foreach (var value in values)
|
|
{
|
|
ret += (!String.IsNullOrEmpty(ret) ? ", " : "") + value.ToDec();
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
public static string ToBin(this byte[] values, bool Add_0b)
|
|
{
|
|
if (values == null) { return "Array is empty!"; }
|
|
string ret = "";
|
|
foreach (var value in values)
|
|
{
|
|
ret += (!String.IsNullOrEmpty(ret) ? ", " : "") + value.ToBin(Add_0b);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
|
|
public static string ToHex(this Int16 value, bool Add_0x)
|
|
{
|
|
return DecimalToHex(value, 4, Add_0x);
|
|
}
|
|
|
|
public static string ToHex(this UInt16 value, bool Add_0x)
|
|
{
|
|
return UnsignedDecimalToHex(value, 4, Add_0x);
|
|
}
|
|
|
|
public static string ToHex(this Int32 value, bool Add_0x)
|
|
{
|
|
return DecimalToHex(value, 8, Add_0x);
|
|
}
|
|
|
|
public static string ToHex(this UInt32 value, bool Add_0x)
|
|
{
|
|
return UnsignedDecimalToHex(value, 8, Add_0x);
|
|
}
|
|
|
|
public static string ToHex(this Int64 value, bool Add_0x)
|
|
{
|
|
return DecimalToHex(value, 16, Add_0x);
|
|
}
|
|
|
|
public static string ToHex(this UInt64 value, bool Add_0x)
|
|
{
|
|
return UnsignedDecimalToHex(value, 16, Add_0x);
|
|
}
|
|
|
|
public static string UnsignedDecimalToBase(this string iDec, int numbase)
|
|
{
|
|
try
|
|
{
|
|
return UnsignedDecimalToBase(Convert.ToUInt64(iDec), numbase);
|
|
}
|
|
catch
|
|
{
|
|
return "?";
|
|
}
|
|
}
|
|
|
|
public static string UnsignedDecimalToBase(this UInt64 iDec, int numbase)
|
|
{
|
|
try
|
|
{
|
|
String strBin = "";
|
|
int[] result = new int[64];
|
|
int MaxBit = 64;
|
|
for (; iDec > 0; iDec /= (UInt64)numbase)
|
|
{
|
|
int rem = (int)(iDec % Convert.ToUInt64(numbase));
|
|
result[--MaxBit] = rem;
|
|
}
|
|
for (int i = 0; i < result.Length; i++)
|
|
{
|
|
if ((int)result.GetValue(i) >= base10)
|
|
{
|
|
strBin += cHexa[(int)result.GetValue(i) % base10];
|
|
}
|
|
else
|
|
{
|
|
strBin += result.GetValue(i);
|
|
}
|
|
}
|
|
strBin = strBin.TrimStart(new char[] { '0' });
|
|
return strBin;
|
|
}
|
|
catch
|
|
{
|
|
return "?";
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Converter string to a value (0x or 0b is not legal)
|
|
/// </summary>
|
|
/// <param name="sBase"></param>
|
|
/// <param name="numbase"></param>
|
|
/// <returns></returns>
|
|
public static UInt64 UnsignedBaseToDecimal(this String sBase, int numbase)
|
|
{
|
|
UInt64 result = 0;
|
|
UInt64 b;
|
|
UInt64 iProduct = 1;
|
|
String sHexa = "";
|
|
if (numbase > base10)
|
|
{
|
|
for (int i = 0; i < cHexa.Length; i++)
|
|
{
|
|
sHexa += cHexa.GetValue(i).ToString();
|
|
}
|
|
}
|
|
for (int i = sBase.Length - 1; i >= 0; i--, iProduct *= (UInt64)numbase)
|
|
{
|
|
String sValue = sBase[i].ToString();
|
|
if (sValue.IndexOfAny(cHexa) >= 0)
|
|
{
|
|
b = (UInt64)iHexaNumeric[sHexa.IndexOf(sBase[i])];
|
|
}
|
|
else
|
|
{
|
|
b = (UInt64)sBase[i] - (UInt64)asciiDiff;
|
|
}
|
|
result += (b * iProduct);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Converter string to a value use 0x or 0b
|
|
/// </summary>
|
|
/// <param name="sBase"></param>
|
|
/// <param name="numbase"></param>
|
|
/// <returns></returns>
|
|
public static UInt64 ToUInt64(this String sBase)
|
|
{
|
|
UInt64 result = 0;
|
|
UInt64 b;
|
|
UInt64 iProduct = 1;
|
|
String sHexa = "";
|
|
int numbase;
|
|
sBase = sBase.Trim().ToLower();
|
|
if (sBase.StartsWith(ValueInputAsOctalFrontTag))
|
|
{
|
|
numbase = 8;
|
|
sBase = sBase.Replace(ValueInputAsOctalFrontTag, "");
|
|
}
|
|
else if (sBase.StartsWith(ValueInputAsHexFrontTag))
|
|
{
|
|
numbase = 16;
|
|
sBase = sBase.Replace(ValueInputAsHexFrontTag, "");
|
|
}
|
|
else if (sBase.StartsWith(ValueInputAsBinaryFrontTag))
|
|
{
|
|
numbase = 2;
|
|
sBase = sBase.Replace(ValueInputAsBinaryFrontTag, "");
|
|
}
|
|
else
|
|
{
|
|
return Convert.ToUInt64(sBase);
|
|
}
|
|
if (numbase > base10)
|
|
{
|
|
for (int i = 0; i < cHexa.Length; i++)
|
|
{
|
|
sHexa += cHexa.GetValue(i).ToString();
|
|
}
|
|
}
|
|
for (int i = sBase.Length - 1; i >= 0; i--, iProduct *= (UInt64)numbase)
|
|
{
|
|
String sValue = sBase[i].ToString();
|
|
if (sValue.IndexOfAny(cHexa) >= 0)
|
|
{
|
|
b = (UInt64)iHexaNumeric[sHexa.IndexOf(sBase[i])];
|
|
}
|
|
else
|
|
{
|
|
b = (UInt64)sBase[i] - (UInt64)asciiDiff;
|
|
}
|
|
result += (b * iProduct);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Converter string to a value use 0x or 0b
|
|
/// </summary>
|
|
/// <param name="sBase"></param>
|
|
/// <param name="numbase"></param>
|
|
/// <returns></returns>
|
|
public static Int64 ToInt64(this String sBase)
|
|
{
|
|
Int64 result = 0;
|
|
Int64 b;
|
|
Int64 iProduct = 1;
|
|
String sHexa = "";
|
|
int numbase;
|
|
bool isNegative = false;
|
|
sBase = sBase.Trim().ToLower();
|
|
if (sBase.StartsWith("-"))
|
|
{
|
|
sBase = sBase.TrimStart('-');
|
|
isNegative = true;
|
|
}
|
|
else if (sBase.StartsWith("+"))
|
|
{
|
|
sBase = sBase.TrimStart('+');
|
|
}
|
|
if (sBase.StartsWith(ValueInputAsOctalFrontTag))
|
|
{
|
|
numbase = 8;
|
|
sBase = sBase.Replace(ValueInputAsOctalFrontTag, "");
|
|
}
|
|
else if (sBase.StartsWith(ValueInputAsHexFrontTag))
|
|
{
|
|
numbase = 16;
|
|
sBase = sBase.Replace(ValueInputAsHexFrontTag, "");
|
|
}
|
|
else if (sBase.StartsWith(ValueInputAsBinaryFrontTag))
|
|
{
|
|
numbase = 2;
|
|
sBase = sBase.Replace(ValueInputAsBinaryFrontTag, "");
|
|
}
|
|
else
|
|
{
|
|
return isNegative ? -Convert.ToInt64(sBase) : Convert.ToInt64(sBase);
|
|
}
|
|
if (numbase > base10)
|
|
{
|
|
for (int i = 0; i < cHexa.Length; i++)
|
|
{
|
|
sHexa += cHexa.GetValue(i).ToString();
|
|
}
|
|
}
|
|
for (int i = sBase.Length - 1; i >= 0; i--, iProduct *= (Int64)numbase)
|
|
{
|
|
String sValue = sBase[i].ToString();
|
|
if (sValue.IndexOfAny(cHexa) >= 0)
|
|
{
|
|
b = (Int64)iHexaNumeric[sHexa.IndexOf(sBase[i])];
|
|
}
|
|
else
|
|
{
|
|
b = (Int64)sBase[i] - (Int64)asciiDiff;
|
|
}
|
|
result += (b * iProduct);
|
|
}
|
|
return isNegative ? -result : result;
|
|
}
|
|
|
|
public static UInt16 SwapByte(this UInt16 value)
|
|
{
|
|
return (UInt16)(value >> 8 | (value & 0xFF) << 8);
|
|
}
|
|
|
|
public static UInt64 SwapWord(this UInt64 value)
|
|
{
|
|
return (UInt64)(value >> 16 | (value & 0xFFFF) << 16);
|
|
}
|
|
|
|
}
|
|
}
|