Related
I am trying an efficient way to split up a string. I have a string in the below format which represents a value.
string input = "1A2B3C4D5DC";
i have to fetch the numeric value next to each character , so that i can compute the final value.
Currently im doing this, This works fine, Can you suggest me a better approach.
public double GetValue(string input)
{
string value;
int beginIndex = 0, endIndex = 0, unit1 = 0, unit2 = 0, unit3 = 0, unit4 = 0, unit5 = 0;
input = input.Replace("cd", "zz");
if (input.ToLower().Contains("a"))
{
endIndex = input.ToLower().IndexOf('a');
value = input.Substring(beginIndex, endIndex - beginIndex);
int.TryParse(value, out unit1);
beginIndex = endIndex + 1;
}
if (input.ToLower().Contains("b"))
{
endIndex = input.ToLower().IndexOf('b');
value = input.Substring(beginIndex, endIndex - beginIndex);
int.TryParse(value, out unit2);
beginIndex = endIndex + 1;
}
if (input.ToLower().Contains("c") )
{
endIndex = input.ToLower().IndexOf('b');
value = input.Substring(beginIndex, endIndex - beginIndex);
int.TryParse(value, out unit3);
beginIndex = endIndex + 1;
}
if (input.ToLower().Contains("d"))
{
endIndex = input.ToLower().IndexOf('d');
value = input.Substring(beginIndex, endIndex - beginIndex);
int.TryParse(value, out unit4);
beginIndex = endIndex + 1;
}
if (input.Length > beginIndex + 2)
{
value = input.Substring(beginIndex, input.Length - beginIndex - 2);
int.TryParse(value, out unit5);
}
return (unit1 * 10 + unit2 * 20 + unit3 * 30 + unit4 * 40 + unit5 * 50); //some calculation
}
Possible inputs can be : 21A34DC , 4C, 2BDC, 2B. basically they all are optional but if present it has to be in the same sequence
you can find all numbers within string with a regular expression:
string input = "1A2B3C4D5DC";
Regex rx = new Regex(#"\d+");
// Regex rx = new Regex(#"-?\d+"); // this one includes negative integers
var matches = rx.Matches(input);
int[] numbers = matches.OfType<Match>()
.Select(m => Convert.ToInt32(m.Value))
.ToArray();
make necessary computations with resulting array.
If you want to extract just numbers from string, then use Regular Expressions:
string input = "1A2B3C4D5DC";
var resultString = Regex.Replace(input, #"[^0-9]+", "");
Or linq way:
string input = "1A2B3C4D5DC";
var resultString = new String(input.Where(Char.IsDigit).ToArray());
Just looking at your code there is a lot of repeating code, so refactoring it "as is" and using a mapping dictionary is likely good solurtion
Something like this
public static double GetValue(string input)
{
var map = new Dictionary<string, int>()
{
{"a", 10 }, {"b", 20}, {"c", 30}, {"d", 40}
};
int result = 0;
foreach(var i in map)
{
int endIndex, outValue;
string value;
endIndex = input.ToLower().IndexOf(i.Key);
value = input.Substring(endIndex -1, 1);
int.TryParse(value, out outValue);
result += (i.Value * outValue);
}
return result;
}
Following code for me ,
public double GetValue(string input)
{
input)= input)();
string value;
int aValue = 0, bValue = 0, cValue = 0, dvalue = 0, cdValue = 0;
if (match.Groups[5].Success && !string.IsNullOrEmpty(match.Groups[5].Value))
{
string val = match.Groups[5].Value;
if (!int.TryParse(val.Substring(0, val.Length - 2), out cdValue))
{
return -1;
}
}
if (match.Groups[4].Success && !string.IsNullOrEmpty(match.Groups[4].Value))
{
string val = match.Groups[4].Value;
if (!int.TryParse(val.Substring(0, val.Length - 1), out dvalue))
{
return -1;
}
}
if (match.Groups[3].Success && !string.IsNullOrEmpty(match.Groups[3].Value))
{
string val = match.Groups[3].Value;
if (!int.TryParse(val.Substring(0, val.Length - 1), out cValue))
{
return -1;
}
}
if (match.Groups[2].Success && !string.IsNullOrEmpty(match.Groups[2].Value))
{
string val = match.Groups[2].Value;
if (!int.TryParse(val.Substring(0, val.Length - 1), out bValue))
{
return -1;
}
}
if (match.Groups[1].Success && !string.IsNullOrEmpty(match.Groups[1].Value))
{
string val = match.Groups[1].Value;
if (!int.TryParse(val.Substring(0, val.Length - 1), out aValue))
{
return -1;
}
}
return (aValue * 10 + bValue * 20 + cValue * 30 + dvalue * 40 + cdValue * 50); //some calculation
}
Tell me if this produces the expected output:
static void Main(string[] args)
{
int sum = GetValue("1A2B3C4D5DC");
// {1,2,3,4,5} = 10*(1+2*2+3*3+4*4+5*5) = 550
}
public static int GetValue(string input)
{
// make input all lowercase
input = input.ToLower();
// replace terminator dc with next letter to
// avoid failing the search;
input = input.Replace("dc", "e");
// initialize all unit values to zero
const string tokens = "abcde";
int[] units = new int[tokens.Length];
// keep track of position of last parsed number
int start = 0;
for (int index = 0; index < tokens.Length; index++)
{
// fetch next letter
char token = tokens[index];
// find letter in input
int position = input.IndexOf(token, start);
// if found
if (position>start)
{
// extract string before letter
string temp = input.Substring(start, position-start);
// and convert to integer
int.TryParse(temp, out units[index]);
}
// update last parsed number
start = position+1;
}
// add unit values, each one worth +10 more than the
// previous one.
//
// {x,y,z} = 10*x + 20*y + 30*z
int sum = 0;
for (int i = 0; i < units.Length; i++)
{
sum += 10*(i+1)*units[i];
}
return sum;
}
}
Please add some test cases in the question with the expected results just to make sure our answers are correct.
"1A2B3C4D5DC" => 550
???
I'm looking for a way to convert a long string of binary to a hex string.
the binary string looks something like this "0110011010010111001001110101011100110100001101101000011001010110001101101011"
I've tried using
hex = String.Format("{0:X2}", Convert.ToUInt64(hex, 2));
but that only works if the binary string fits into a Uint64 which if the string is long enough it won't.
is there another way to convert a string of binary into hex?
Thanks
I just knocked this up. Maybe you can use as a starting point...
public static string BinaryStringToHexString(string binary)
{
if (string.IsNullOrEmpty(binary))
return binary;
StringBuilder result = new StringBuilder(binary.Length / 8 + 1);
// TODO: check all 1's or 0's... throw otherwise
int mod4Len = binary.Length % 8;
if (mod4Len != 0)
{
// pad to length multiple of 8
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();
}
This might help you:
string HexConverted(string strBinary)
{
string strHex = Convert.ToInt32(strBinary,2).ToString("X");
return strHex;
}
Convert.ToInt32("1011", 2).ToString("X");
For string longer than this, you can simply break it into multiple bytes:
var binary = "0110011010010111001001110101011100110100001101101000011001010110001101101011";
var hex = string.Join(" ",
Enumerable.Range(0, binary.Length / 8)
.Select(i => Convert.ToByte(binary.Substring(i * 8, 8), 2).ToString("X2")));
I came up with this method. I am new to programming and C# but I hope you will appreciate it:
static string BinToHex(string bin)
{
StringBuilder binary = new StringBuilder(bin);
bool isNegative = false;
if (binary[0] == '-')
{
isNegative = true;
binary.Remove(0, 1);
}
for (int i = 0, length = binary.Length; i < (4 - length % 4) % 4; i++) //padding leading zeros
{
binary.Insert(0, '0');
}
StringBuilder hexadecimal = new StringBuilder();
StringBuilder word = new StringBuilder("0000");
for (int i = 0; i < binary.Length; i += 4)
{
for (int j = i; j < i + 4; j++)
{
word[j % 4] = binary[j];
}
switch (word.ToString())
{
case "0000": hexadecimal.Append('0'); break;
case "0001": hexadecimal.Append('1'); break;
case "0010": hexadecimal.Append('2'); break;
case "0011": hexadecimal.Append('3'); break;
case "0100": hexadecimal.Append('4'); break;
case "0101": hexadecimal.Append('5'); break;
case "0110": hexadecimal.Append('6'); break;
case "0111": hexadecimal.Append('7'); break;
case "1000": hexadecimal.Append('8'); break;
case "1001": hexadecimal.Append('9'); break;
case "1010": hexadecimal.Append('A'); break;
case "1011": hexadecimal.Append('B'); break;
case "1100": hexadecimal.Append('C'); break;
case "1101": hexadecimal.Append('D'); break;
case "1110": hexadecimal.Append('E'); break;
case "1111": hexadecimal.Append('F'); break;
default:
return "Invalid number";
}
}
if (isNegative)
{
hexadecimal.Insert(0, '-');
}
return hexadecimal.ToString();
}
Considering four bits can be expressed by one hex value, you can simply go by groups of four and convert them seperately, the value won't change that way.
string bin = "11110110";
int rest = bin.Length % 4;
if(rest != 0)
bin = new string('0', 4-rest) + bin; //pad the length out to by divideable by 4
string output = "";
for(int i = 0; i <= bin.Length - 4; i +=4)
{
output += string.Format("{0:X}", Convert.ToByte(bin.Substring(i, 4), 2));
}
If you want to iterate over the hexadecimal representation of each byte in the string, you could use the following extension. I've combined Mitch's answer with this.
static class StringExtensions
{
public static IEnumerable<string> ToHex(this String s) {
if (s == null)
throw new ArgumentNullException("s");
int mod4Len = s.Length % 8;
if (mod4Len != 0)
{
// pad to length multiple of 8
s = s.PadLeft(((s.Length / 8) + 1) * 8, '0');
}
int numBitsInByte = 8;
for (var i = 0; i < s.Length; i += numBitsInByte)
{
string eightBits = s.Substring(i, numBitsInByte);
yield return string.Format("{0:X2}", Convert.ToByte(eightBits, 2));
}
}
}
Example:
string test = "0110011010010111001001110101011100110100001101101000011001010110001101101011";
foreach (var hexVal in test.ToHex())
{
Console.WriteLine(hexVal);
}
Prints
06
69
72
75
73
43
68
65
63
6B
If you're using .NET 4.0 or later and if you're willing to use System.Numerics.dll (for BigInteger class), the following solution works fine:
public static string ConvertBigBinaryToHex(string bigBinary)
{
BigInteger bigInt = BigInteger.Zero;
int exponent = 0;
for (int i = bigBinary.Length - 1; i >= 0; i--, exponent++)
{
if (bigBinary[i] == '1')
bigInt += BigInteger.Pow(2, exponent);
}
return bigInt.ToString("X");
}
Considering four bits can be expressed by one hex value, you can simply go by groups of four and convert them seperately, the value won't change that way.
string bin = "11110110";
int rest = bin.Length % 4;
bin = bin.PadLeft(rest, '0'); //pad the length out to by divideable by 4
string output = "";
for(int i = 0; i <= bin.Length - 4; i +=4)
{
output += string.Format("{0:X}", Convert.ToByte(bin.Substring(i, 4), 2));
}
static string BinToHex(string bin)
{
if (bin == null)
throw new ArgumentNullException("bin");
if (bin.Length % 8 != 0)
throw new ArgumentException("The length must be a multiple of 8", "bin");
var hex = Enumerable.Range(0, bin.Length / 8)
.Select(i => bin.Substring(8 * i, 8))
.Select(s => Convert.ToByte(s, 2))
.Select(b => b.ToString("x2"));
return String.Join(null, hex);
}
Using LINQ
string BinaryToHex(string binaryString)
{
var offset = 0;
StringBuilder sb = new();
while (offset < binaryString.Length)
{
var nibble = binaryString
.Skip(offset)
.Take(4);
sb.Append($"{Convert.ToUInt32(nibble.toString()), 2):X}");
offset += 4;
}
return sb.ToString();
}
You can take the input number four digit at a time. Convert this digit to ex ( as you did is ok ) then concat the string all together. So you obtain a string representing the number in hex, independetly from the size. Depending on where start MSB on your input string, may be the output string you obtain the way i described must be reversed.
I have a string which is alphanumeric. From this string I created a byte array:
var endoding = Encoding.ASCII.GetBytes("123abcABC");
The length of the string is equal to the length of the ASCII byte array encoding.Length , that is 9.
I want to squeeze this encoded array length to less than 9. So I am looking for
Six-bit corrector code techniques
I wrote a sample (row) function based on the my understanding but it is failing for cap letters.
test case 1.
string input = "ABCDEFGH"; // length = 8
var Bytes1 = ConvertToEightBitCode(input ); // length = 6
var output = GetRxString(Bytes1); // input == output
test case 2
string input = "ABCDEFGH123"; // length = 11
var rxBytes1 = ConvertToEightBitCode(input ); // length = 9
var output = GetRxString(Bytes1); // input == output
test case 3 (failed)
string input = "abcABC123"; // length = 9
var rxBytes1 = ConvertToEightBitCode(input ); // length = 8
var output = GetRxString(Bytes1); // input != output
This function needs much improvement.
public static byte[] ConvertToEightBitCode(string rxNumber)
{
var asciiBytes = Encoding.ASCII.GetBytes(rxNumber);
//Console.WriteLine("Actual ASCII rx bytes [{0}]", string.Join(", ", asciiBytes));
byte[] newasciiByte = new byte[asciiBytes.Length];
byte tt = 32;
for (int i = 0; i < asciiBytes.Length; i++)
{
newasciiByte[i] = (byte)(asciiBytes[i] - tt);
}
//Console.WriteLine("Converted ASCII rx bytes [{0}]", string.Join(", ", newasciiByte));
string datastring = "";
foreach (var item in newasciiByte)
{
var e = Convert.ToString(item, 2);
var pe = e.Length == 6 ? e : e.PadLeft(6, '0');
datastring += pe;
}
//Console.WriteLine("Binary string [{0}]", datastring);
int factor = GetDevideNum(datastring.Length, 8);
List<string> new8Binary = new List<string>();
for (int i = 0; i < factor; i++)
{
var s = GetCharString(datastring.ToCharArray(), i * 8, 8);
if (!string.IsNullOrEmpty(s))
{
new8Binary.Add(s);
}
}
//Console.WriteLine("New eight block binary string array [{0}]", string.Join(", ", new8Binary));
List<byte> new8bytes = new List<byte>();
foreach (var item in new8Binary)
{
var ii = Convert.ToByte(item, 2);
new8bytes.Add(ii);
}
//Console.WriteLine("New Ascii bytes values for rx [{0}]", string.Join(", ", new8bytes));
return new8bytes.ToArray();
}
public static string GetRxString(byte[] rxarray)
{
//Console.WriteLine("Input Ascii rx array values for rx [{0}]", string.Join(", ", rxarray));
List<string> eightpadBinarystringArray = new List<string>();
for (int i = 0; i < rxarray.Length; i++)
{
var ss = Convert.ToString(rxarray[i], 2);
if (i == rxarray.Length - 1 && ss != "0")
eightpadBinarystringArray.Add(GetExactBinary(ss));
else
eightpadBinarystringArray.Add(ss.PadLeft(8, '0'));
}
//Console.WriteLine("Converted eight block binary string array [{0}]", string.Join(", ", eightpadBinarystringArray));
string eightpadBinarystring = string.Join("", eightpadBinarystringArray);
//Console.WriteLine("Converted binary string array [{0}]", string.Join(", ", eightpadBinarystring));
int factor = GetDevideNum(eightpadBinarystring.Length, 6);
//eightpadBinarystring = 100001100010100011100100100101100110100111
List<string> sixpadBinarystringArray = new List<string>();
for (int i = 0; i < factor; i++)
{
var sixxx = GetCharString(eightpadBinarystring.ToCharArray(), i * 6, 6);
if (!string.IsNullOrEmpty(sixxx))
{
sixpadBinarystringArray.Add(sixxx);
}
}
//Console.WriteLine("Converted six pad block binary string array [{0}]", string.Join(", ", sixpadBinarystringArray));
List<byte> result = new List<byte>();
foreach (var item in sixpadBinarystringArray)
{
var rr = Convert.ToByte(item, 2);
var bbr = (byte)(rr + 32);
result.Add(bbr);
}
//Console.WriteLine("Converted ascii array [{0}]", string.Join(", ", result));
StringBuilder rxNumber = new StringBuilder();
foreach (var item in result)
{
if (item != 32)
{
char c = (char)item;
rxNumber.Append(c);
}
}
//Console.WriteLine("Converted char array [{0}]", string.Join(", ", clist));
return rxNumber.ToString();
}
private static int GetDevideNum(int length, int f)
{
if (length % f == 0)
{
return length / f;
}
else
{
return length / f + 1;
}
}
private static string GetExactBinary(string ss)
{
return ss.TrimStart(new char[] { '0' });
}
private static string GetCharString(char[] array, int start, int length)
{
int e = start + length;
char[] dd = new char[length];
for (int i = 0; i < length; i++)
{
dd[i] = ' ';
}
if (e <= array.Length)
{
Array.Copy(array, start, dd, 0, length);
return string.Join("", dd);
}
else
{
int ne = array.Length - start;
if (ne == 0)
{
return "";
}
Array.Copy(array, start, dd, 0, ne);
var data = string.Join("", dd).Trim();
string rdata = data.PadLeft(length, '0');
return rdata;
}
}
I use six bit encoding from wiki
table CDC 1612 printer codes (business applications)
input is ABC1234
A - 31 = hex to binary = 0011 0001 - six bit - 110001 -- six bit padding
B - 32 = hex to binary = 0011 0010 - six bit - 110010
C - 33 = hex to binary = 0011 0011 - six bit - 110011
1- 01 = hex to binary = 0000 0001 - six bit - 000001
2-02 = hex to binary = 0000 0010 - six bit - 000010
3- 03 = hex to binary = 0000 0011 - six bit - 000011
4 -03 = hex to binary = 0000 0100 - six bit - 000100
New six bit
110001110010110011000001000010000011000100
New eight bit pading
000000110001110010110011000001000010000011000100
Eight bit array
00000011 - binary to dec - 3
00011100 - binary to dec - 28
10110011 - binary to dec - 179
00000100 - binary to dec - 4
00100000 - binary to dec - 32
11000100 - binary to dec - 196
New aaray
3 -- dec to binary - 00000011 -- eight bit padding
28 -- dec to binary - 00011100
179 -- dec to binary - 10110011
4 -- dec to binary - 00000100
32 -- dec to binary - 00100000
196 -- dec to binary - 11000100
8 bit String
000000110001110010110011000001000010000011000100
Six bit padding
000000110001110010110011000001000010000011000100
000000 -- binary to hex -- 0 -- first ignore
110001 -- binary to hex -- 31 -- A
110010 -- binary to hex -- 32 -- B
110011 -- binary to hex -- 33 -- C
000001 -- binary to hex -- 01 -- 1
000010 -- binary to hex -- 02 -- 2
000011 -- binary to hex -- 03 -- 3
000100 -- binary to hex -- 04 -- 4
my c# code for this
namespace NewApproachSixBitEncodeApp
{
class Program
{
static int maxLength = 28;
static void Main(string[] args)
{
try
{
string input = args[0];//"::AB:C1234::AB:C1234::AB:C12";
if (args.Length <= 0
|| string.IsNullOrEmpty(args[0]))
{
throw new Exception("Input not correct please enter valid rx string.");
}
byte[] encode = Encode(input);
string output = Decode(encode);
Console.WriteLine("\ninput: [{0}] \ninput ecoded array [{1}] \ninput rx length: [{2}] \noutput encode array: [{3}] \noutput.encoded.length: [{4}] \noutput decoded: [{5}]",
input, string.Join(", ", Encoding.ASCII.GetBytes(input)), input.Length, string.Join(", ", encode), encode.Length, output);
}
catch (Exception ex)
{
Console.WriteLine("Error : " + ex.Message);
}
Console.ReadLine();
}
static ReferenceTable referenceTable = ReferenceTableValue.Create();
public static string Decode(byte[] encode)
{
string binary = "";
foreach (var item in encode)
{
binary += Convert.ToString(item, 2).PadLeft(8, '0');
}
while (binary.Length % 6 != 0)
binary = "0" + binary;
var sixPadBitbinaryArray = Enumerable.Range(0, binary.Length / 6).
Select(pos => binary.Substring(pos * 6, 6)
).ToArray();
StringBuilder result = new StringBuilder();
int count = 0;
foreach (var item in sixPadBitbinaryArray)
{
string element = Convert.ToInt32(item, 2).ToString("X").PadLeft(2, '0');
if (element == "00" && count == 0)
{
count++;
continue;
}
count++;
result.Append(referenceTable.GetChar(element[0].ToString(), element[1].ToString()));
}
return result.ToString();
}
public static byte[] Encode(string input)
{
if (!referenceTable.IsValidString(input))
{
throw new Exception("invalid string. use char from table" + input);
}
string eightPadBitbinary = "";
foreach (var item in input.ToCharArray())
eightPadBitbinary += hex2binaryWithSixPadding(referenceTable[item]);
while (eightPadBitbinary.Length % 8 != 0)
eightPadBitbinary = "0" + eightPadBitbinary;
var eightPadBitbinaryArray = Enumerable.Range(0, eightPadBitbinary.Length / 8).
Select(pos => Convert.ToByte(eightPadBitbinary.Substring(pos * 8, 8),
2)
).ToArray();
return eightPadBitbinaryArray;
}
static string hex2binaryWithSixPadding(string hexvalue)
{
var hexToBin = String.Join(String.Empty, hexvalue.Select(c => Convert.ToString(Convert.ToUInt32(c.ToString(), 16), 2).PadLeft(4, '0')));
string result = hexToBin;
while (result.Length > 6 && result.StartsWith("0"))
result = hexToBin.TrimStart(new char[] { '0' }); ;
if (result.Length > 6)
throw new Exception("hex to bin length error HexValue = " + hexvalue);
else
result = result.PadLeft(6, '0');
return result;
}
}
public class ReferenceTableValue
{
//CDC 1612 printer codes (business applications)
private ReferenceTableValue()
{
}
public string GetAllChar()
{
return string.Join("", list);
}
static List<string> list = new List<string>();
public static ReferenceTable Create()
{
ReferenceTable t = new ReferenceTable();
t.ReferenceTableValues = new List<ReferenceTableValue>();
list.Add(":1234567890=≠≤![");
list.Add(" /STUVWXYZ],(→≡~");
list.Add("-JKLMNOPQR%$*↑↓>");
list.Add("+ABCDEFGHI<.)≥?;");
for (int row = 0; row <= 3; row++)
{
for (int col = 0; col <= 15; col++)
{
char cc = list[row].Substring(col, 1).ToCharArray()[0];
ReferenceTableValue rf = new ReferenceTableValue(
String.Format("{0:X}", row),
String.Format("{0:X}", col),
cc);
t.ReferenceTableValues.Add(rf);
}
}
return t;
}
public ReferenceTableValue(string x, string y, char charector)
{
this.X = x;
this.Y = y;
this.Charector = charector;
}
public string X { get; set; }
public string Y { get; set; }
public char Charector { get; set; }
}
public class ReferenceTable
{
public List<ReferenceTableValue> ReferenceTableValues { get; set; }
public bool IsValidString(string input)
{
if (string.IsNullOrWhiteSpace(input)
|| ReferenceTableValues == null
|| ReferenceTableValues.Count == 0)
return false;
var refval = ReferenceTableValues[0];
string allStringChar = refval.GetAllChar();
foreach (var item in input.ToCharArray())
{
if (!allStringChar.Contains(item))
{
return false;
}
}
return true;
}
public string this[char val]
{
get
{
if (ReferenceTableValues == null) return null;
foreach (var item in ReferenceTableValues)
{
if ((int)item.Charector == (int)val)
{
return item.X + item.Y;
}
}
throw new Exception(string.Format("Value not found for char [{0}]", val.ToString()));
}
}
public char GetChar(string _x, string _y)
{
if (ReferenceTableValues == null)
return '\0';
foreach (var item in ReferenceTableValues)
{
if (item.X == _x && item.Y == _y)
return item.Charector;
}
throw new Exception(string.Format("value not found."));
}
}
}
I was wondering how I would convert a string of four to six digits to a date in C#?
111110 would be 11 11 10
111 10 would be 11 1 10
1 1 10 would be 1 1 10
The pattern being mmddyy mmd yy m d yy
and the spaces are either ' ' or '\0' (the input I am given is not very clean)
This what I have so far and it works for all above cases, its just not very pretty:
Is there a more efficient solution to the above cases?
//Converts the given input string into a valid Date
private DateTime convertToDateFromString(string dateString)
{
int length = dateString.Length;
int month = 1;
int day = 1;
int year = 1;
bool gotMonth = false;
bool gotDay = false;
bool gotYear = false;
char c = ' ';
char peek = ' ';
string buffer = "";
DateTime bufferDate;
int count = 0;
try
{
//loop character by character through the string
for (int i = 0; i < dateString.Length; i++)
{
c = dateString[i];
if ((i + 1) < dateString.Length)
peek = dateString[i + 1];
else
peek = '\0';
if (c != ' ' && c != '\0')
{
buffer += c;
count++;
//Check if the month is done
if ((peek == ' ' || peek == '\0' || count == 2) && gotMonth == false)
{
count = 0;
gotMonth = true;
month = int.Parse(buffer);
buffer = null;
}
//Check if the day is done
else if ((peek == ' ' || peek == '\0' || count == 2) && gotDay == false && gotMonth == true)
{
count = 0;
gotDay = true;
day = int.Parse(buffer);
buffer = null;
}
//Check if the year is done
else if ((peek == ' ' || peek == '\0' || count == 2) && gotYear == false && gotMonth == true && gotDay == true)
{
count = 0;
gotYear = true;
year = int.Parse(buffer);
buffer = null;
if (year >= 80 && year <= 99)
year += 1900;
else if (year >= 0 && year <= 79)
year += 2000;
}
}
}
bufferDate = new DateTime(year, month, day);
}
catch (System.Exception ex)
{
bufferDate = new DateTime(1, 1, 1);
}
return bufferDate;
}
You discriminator here is the number of spaces. First get that:
string source = "....";
int spaceCount = source.Count(c => c == ' ');
Then create formatstrings for the expected range 0..2 . You can use the strings from the question except that you have to use M for the months:
var formats = new string[] { "MMddyy", "MMd yy", "M d yy" };
and then you can get your date :
DateTime r = DateTime.ParseExact(source, formats[spaceCount], null);
Add validations as required.
Try using
DateTime.TryParseExact(dateString, new string[] { "MMddyy", "MMd yy", "M d yy" }, CultureInfo.CurrentCulture, DateTimeStyles.AssumeLocal, out result);
if you need to you can
dateString = dateString.Replace('\0', ' ');
before you begin
You should use one of the many Parse methods defined on DateTime.
These will take the string, an optional format string (describing the format of the datetime string) and an optional culture.
Take a look at Parse, ParseExact, TryParse and TryParseExact, some of which will take a string[] of the formats to try.
Additionally, here available string formats - standard and custom date and time format strings.
I'm looking for a way to convert a long string of binary to a hex string.
the binary string looks something like this "0110011010010111001001110101011100110100001101101000011001010110001101101011"
I've tried using
hex = String.Format("{0:X2}", Convert.ToUInt64(hex, 2));
but that only works if the binary string fits into a Uint64 which if the string is long enough it won't.
is there another way to convert a string of binary into hex?
Thanks
I just knocked this up. Maybe you can use as a starting point...
public static string BinaryStringToHexString(string binary)
{
if (string.IsNullOrEmpty(binary))
return binary;
StringBuilder result = new StringBuilder(binary.Length / 8 + 1);
// TODO: check all 1's or 0's... throw otherwise
int mod4Len = binary.Length % 8;
if (mod4Len != 0)
{
// pad to length multiple of 8
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();
}
This might help you:
string HexConverted(string strBinary)
{
string strHex = Convert.ToInt32(strBinary,2).ToString("X");
return strHex;
}
Convert.ToInt32("1011", 2).ToString("X");
For string longer than this, you can simply break it into multiple bytes:
var binary = "0110011010010111001001110101011100110100001101101000011001010110001101101011";
var hex = string.Join(" ",
Enumerable.Range(0, binary.Length / 8)
.Select(i => Convert.ToByte(binary.Substring(i * 8, 8), 2).ToString("X2")));
I came up with this method. I am new to programming and C# but I hope you will appreciate it:
static string BinToHex(string bin)
{
StringBuilder binary = new StringBuilder(bin);
bool isNegative = false;
if (binary[0] == '-')
{
isNegative = true;
binary.Remove(0, 1);
}
for (int i = 0, length = binary.Length; i < (4 - length % 4) % 4; i++) //padding leading zeros
{
binary.Insert(0, '0');
}
StringBuilder hexadecimal = new StringBuilder();
StringBuilder word = new StringBuilder("0000");
for (int i = 0; i < binary.Length; i += 4)
{
for (int j = i; j < i + 4; j++)
{
word[j % 4] = binary[j];
}
switch (word.ToString())
{
case "0000": hexadecimal.Append('0'); break;
case "0001": hexadecimal.Append('1'); break;
case "0010": hexadecimal.Append('2'); break;
case "0011": hexadecimal.Append('3'); break;
case "0100": hexadecimal.Append('4'); break;
case "0101": hexadecimal.Append('5'); break;
case "0110": hexadecimal.Append('6'); break;
case "0111": hexadecimal.Append('7'); break;
case "1000": hexadecimal.Append('8'); break;
case "1001": hexadecimal.Append('9'); break;
case "1010": hexadecimal.Append('A'); break;
case "1011": hexadecimal.Append('B'); break;
case "1100": hexadecimal.Append('C'); break;
case "1101": hexadecimal.Append('D'); break;
case "1110": hexadecimal.Append('E'); break;
case "1111": hexadecimal.Append('F'); break;
default:
return "Invalid number";
}
}
if (isNegative)
{
hexadecimal.Insert(0, '-');
}
return hexadecimal.ToString();
}
Considering four bits can be expressed by one hex value, you can simply go by groups of four and convert them seperately, the value won't change that way.
string bin = "11110110";
int rest = bin.Length % 4;
if(rest != 0)
bin = new string('0', 4-rest) + bin; //pad the length out to by divideable by 4
string output = "";
for(int i = 0; i <= bin.Length - 4; i +=4)
{
output += string.Format("{0:X}", Convert.ToByte(bin.Substring(i, 4), 2));
}
If you want to iterate over the hexadecimal representation of each byte in the string, you could use the following extension. I've combined Mitch's answer with this.
static class StringExtensions
{
public static IEnumerable<string> ToHex(this String s) {
if (s == null)
throw new ArgumentNullException("s");
int mod4Len = s.Length % 8;
if (mod4Len != 0)
{
// pad to length multiple of 8
s = s.PadLeft(((s.Length / 8) + 1) * 8, '0');
}
int numBitsInByte = 8;
for (var i = 0; i < s.Length; i += numBitsInByte)
{
string eightBits = s.Substring(i, numBitsInByte);
yield return string.Format("{0:X2}", Convert.ToByte(eightBits, 2));
}
}
}
Example:
string test = "0110011010010111001001110101011100110100001101101000011001010110001101101011";
foreach (var hexVal in test.ToHex())
{
Console.WriteLine(hexVal);
}
Prints
06
69
72
75
73
43
68
65
63
6B
If you're using .NET 4.0 or later and if you're willing to use System.Numerics.dll (for BigInteger class), the following solution works fine:
public static string ConvertBigBinaryToHex(string bigBinary)
{
BigInteger bigInt = BigInteger.Zero;
int exponent = 0;
for (int i = bigBinary.Length - 1; i >= 0; i--, exponent++)
{
if (bigBinary[i] == '1')
bigInt += BigInteger.Pow(2, exponent);
}
return bigInt.ToString("X");
}
Considering four bits can be expressed by one hex value, you can simply go by groups of four and convert them seperately, the value won't change that way.
string bin = "11110110";
int rest = bin.Length % 4;
bin = bin.PadLeft(rest, '0'); //pad the length out to by divideable by 4
string output = "";
for(int i = 0; i <= bin.Length - 4; i +=4)
{
output += string.Format("{0:X}", Convert.ToByte(bin.Substring(i, 4), 2));
}
static string BinToHex(string bin)
{
if (bin == null)
throw new ArgumentNullException("bin");
if (bin.Length % 8 != 0)
throw new ArgumentException("The length must be a multiple of 8", "bin");
var hex = Enumerable.Range(0, bin.Length / 8)
.Select(i => bin.Substring(8 * i, 8))
.Select(s => Convert.ToByte(s, 2))
.Select(b => b.ToString("x2"));
return String.Join(null, hex);
}
Using LINQ
string BinaryToHex(string binaryString)
{
var offset = 0;
StringBuilder sb = new();
while (offset < binaryString.Length)
{
var nibble = binaryString
.Skip(offset)
.Take(4);
sb.Append($"{Convert.ToUInt32(nibble.toString()), 2):X}");
offset += 4;
}
return sb.ToString();
}
You can take the input number four digit at a time. Convert this digit to ex ( as you did is ok ) then concat the string all together. So you obtain a string representing the number in hex, independetly from the size. Depending on where start MSB on your input string, may be the output string you obtain the way i described must be reversed.