Extracting values from string input - c#

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
???

Related

How to convert a string of bits to a HEX [duplicate]

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.

Implementing six bit character code in C#

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."));
}
}
}

How to improve efficiency - string representation of an integer using standard incremental routine

I created a thread for this but then deleted it as I wasnt making myself clear.
This routine (my code) gives me the string representation of currentCombination.
using System;
using System.Collections.Generic;
namespace SlowGen
{
class MyClass
{
private List<char> _data = new List<char>();
private List<char> _c;
public MyClass(List<char> chars, Int64 currentCombination)
{
_c = chars;
_data.Add(_c[0]);
for (int i = 0; i < currentCombination - 1; i++)
{
if (i < currentCombination - _c.Count)
IncrementFast();
else
Increment();
}
}
public void Increment()
{
Increment(0);
}
public void Increment(int charIndex)
{
if (charIndex + 1 > _data.Count)
_data.Add(_c[0]);
else
{
if (_data[charIndex] != _c[_c.Count - 1])
{
_data[charIndex] = _c[_c.IndexOf(_data[charIndex]) + 1];
}
else
{
_data[charIndex] = _c[0];
Increment(charIndex + 1);
}
}
}
public void IncrementFast()
{
IncrementFast(0);
}
public void IncrementFast(int charIndex)
{
if (charIndex + 1 > _data.Count)
_data.Add(_c[0]);
else
{
if (_data[charIndex] != _c[_c.Count - 1])
{
_data[charIndex] = _c[_c.Count-1];
}
else
{
_data[charIndex] = _c[0];
Increment(charIndex + 1);
}
}
}
public string Value
{
get
{
string output = string.Empty;
foreach (char c in _data)
output = c + output;
return output;
}
}
}
}
Using this example would create A,B,C,AA,AB,AC,BA etc..
List<char> a = new List<char>();
a.Add('A');
a.Add('B');
a.Add('C');
MyClass b = new MyClass(a,3);
//b.Value: C
MyClass c = new MyClass(a,4);
//c.Value: AA
Now I have this code, which is much more efficient, but the patter differs
static void Main(string[] args)
{
char[] r = new char[] { 'A', 'B', 'C' };
for (int i = 0; i <= 120; i++)
{
string xx = IntToString(i, r);
Console.WriteLine(xx);
System.Threading.Thread.Sleep(100);
}
Console.ReadKey();
}
public static string IntToString(int value, char[] baseChars)
{
string result = string.Empty;
int targetBase = baseChars.Length;
do
{
result = baseChars[value % targetBase] + result;
value = value / targetBase;
}
while (value > 0);
return result;
}
It outputs A,B,C,BA,BB,
I need the sequence of the first section of code with the elegance of the second, can anyone advise?
Thankyou
You need the behaviour to change for columns besides the units column, as you've no doubt noticed. Since the values for non-units column you see are 1 too high, you need to compensate by subtracting 1 first. Or at least that's what seemed to work here:
public static string IntToString(int value, char[] baseChars)
{
string result = string.Empty;
int targetBase = baseChars.Length;
do
{
int currentValue = value % targetBase;
result = baseChars[currentValue] + result;
value = value - currentValue; //possibly not necessary due to integer division rounding down anyway
value = value / targetBase;
value = value - 1;
}
while (value > -1);
return result;
}
Here are some worked examples:
6 with targetBase 2 is AAA:
6%2 is 0, place A on right, half to 3, subtract 1 to 2
2%2 is 0, place A, half to 1, subtract 1 to 0
0%2 is 0, place A, we're done
5 with targetBase 2 is BB:
5%2 is 1, place B on right, subtract 1, half to 2, subtract 1 to 1
1%2 is 1, place B, subtract 1, we're done
7 with target base 3 is BB:
7%3 is 1, place B on right, subtract 1 to 6, 1/3 to 2, subtract 1 to 1
1%3 is 1, place B on right, subtract 1, we're done

Mask out part first 12 characters of string with *?

How can I take the value 123456789012345 or 1234567890123456 and turn it into:
************2345 and ************3456
The difference between the strings above is that one contains 15 digits and the other contains 16.
I have tried the following, but it does not keep the last 4 digits of the 15 digit number and now matter what the length of the string, be it 13, 14, 15, or 16, I want to mask all beginning digits with a *, but keep the last 4. Here is what I have tried:
String.Format("{0}{1}", "************", str.Substring(11, str.Length - 12))
Something like this:
string s = "1234567890123"; // example
string result = s.Substring(s.Length - 4).PadLeft(s.Length, '*');
This will mask all but the last four characters of the string. It assumes that the source string is at least 4 characters long.
using System;
class Program
{
static void Main()
{
var str = "1234567890123456";
if (str.Length > 4)
{
Console.WriteLine(
string.Concat(
"".PadLeft(12, '*'),
str.Substring(str.Length - 4)
)
);
}
else
{
Console.WriteLine(str);
}
}
}
Easiest way: Create an extension method to extract the last four digits. Use that in your String.Format call.
For example:
public static string LastFour(this string value)
{
if (string.IsNullOrEmpty(value) || value.length < 4)
{
return "0000";
}
return value.Substring(value.Length - 4, 4)
}
In your code:
String.Format("{0}{1}", "************", str.LastFour());
In my opinion, this leads to more readable code, and it's reusable.
EDIT: Perhaps not the easiest way, but an alternative way that may produce more maintainable results. <shrug/>
Try this:
var maskSize = ccDigits.Length - 4;
var mask = new string('*', maskSize) + ccDigits.Substring(maskSize);
LINQ:
char maskBy = '*';
string input = "123456789012345";
int count = input.Length <= 4 ? 0 : input.Length - 4;
string output = new string(input.Select((c, i) => i < count ? maskBy : c).ToArray());
static private String MaskInput(String input, int charactersToShowAtEnd)
{
if (input.Length < charactersToShowAtEnd)
{
charactersToShowAtEnd = input.Length;
}
String endCharacters = input.Substring(input.Length - charactersToShowAtEnd);
return String.Format(
"{0}{1}",
"".PadLeft(input.Length - charactersToShowAtEnd, '*'),
endCharacters
);
}
Adjust the function header as required, call with:
MaskInput("yourInputHere", 4);
private string MaskDigits(string input)
{
//take first 6 characters
string firstPart = input.Substring(0, 6);
//take last 4 characters
int len = input.Length;
string lastPart = input.Substring(len - 4, 4);
//take the middle part (****)
int middlePartLenght = len - (firstPart.Length + lastPart.Length);
string middlePart = new String('*', middlePartLenght);
return firstPart + middlePart + lastPart;
}
MaskDigits("1234567890123456");
// output : "123456******3456"
Try the following:
private string MaskString(string s)
{
int NUM_ASTERISKS = 4;
if (s.Length < NUM_ASTERISKS) return s;
int asterisks = s.Length - NUM_ASTERISKS;
string result = new string('*', asterisks);
result += s.Substring(s.Length - NUM_ASTERISKS);
return result;
}
Regex with a match evaluator will do the job
string filterCC(string source) {
var x=new Regex(#"^\d+(?=\d{4}$)");
return x.Replace(source,match => new String('*',match.Value.Length));
}
This will match any number of digits followed by 4 digits and the end (it won't include the 4 digits in the replace). The replace function will replace the match with a string of * of equal length.
This has the additional benefit that you could use it as a validation algorthim too. Change the first + to {11,12} to make it match a total of 15 or 16 chars and then you can use x.IsMatch to determine validity.
EDIT
Alternatively if you always want a 16 char result just use
return x.Replace(source,new String('*',12));
// "123456789".MaskFront results in "****56789"
public static string MaskFront(this string str, int len, char c)
{
var strArray = str.ToCharArray();
for (var i = 0; i < len; i++)
{
if(i < strArray.Length)
{
strArray[i] = c;
}
else
{
break;
}
}
return string.Join("", strArray);
}
// "123456789".MaskBack results in "12345****"
public static string MaskBack(this string str, int len, char c)
{
var strArray = str.ToCharArray();
var tracker = strArray.Length - 1;
for (var i = 0; i < len; i++)
{
if (tracker > -1)
{
strArray[tracker] = c;
tracker--;
}
else
{
break;
}
}
return string.Join("", strArray);
}
Try this out:
static string Mask(string str)
{
if (str.Length <= 4) return str;
Regex rgx = new Regex(#"(.*?)(\d{4})$");
string result = String.Empty;
if (rgx.IsMatch(str))
{
for (int i = 0; i < rgx.Matches(str)[0].Groups[1].Length; i++)
result += "*";
result += rgx.Matches(str)[0].Groups[2];
return result;
}
return str;
}
Mask from start and from end with sending char
public static string Maskwith(this string value, int fromStart, int fromEnd, char ch)
{
return (value?.Length >= fromStart + fromEnd) ?
string.Concat(Enumerable.Repeat(ch, fromStart)) + value.Substring(fromStart, value.Length - (fromStart + fromEnd)) + string.Concat(Enumerable.Repeat(ch, fromEnd))
: "";
} //Console.WriteLine("mytestmask".Maskwith(2,3,'*')); **testm***
show chars from start and from end by passing value and mask the middle
public static string MasktheMiddle(this string value, int visibleCharLength, char ch)
{
if (value?.Length <= (visibleCharLength * 2))
return string.Concat(Enumerable.Repeat(ch,value.Length));
else
return value.Substring(0, visibleCharLength) + string.Concat(Enumerable.Repeat(ch, value.Length - (visibleCharLength * 2))) + value.Substring(value.Length - visibleCharLength);
} //Console.WriteLine("mytestmask".MasktheMiddle(2,'*')); Result: my******sk
How can I take the value 123456789012345 or 1234567890123456 and turn it into:
************2345 and ************3456
one more way to do this:
var result = new string('*',0,value.Length - 4) + new string(value.Skip(value.Length - 4).ToArray())
// or using string.Join
An extension method using C# 8's index and range:
public static string MaskStart(this string input, int showNumChars, char maskChar = '*') =>
input[^Math.Min(input.Length, showNumChars)..]
.PadLeft(input.Length, maskChar);
A simple way
string s = "1234567890123"; // example
int l = s.Length;
s = s.Substring(l - 4);
string r = new string('*', l);
r = r + s;

How to convert numbers between hexadecimal and decimal

How do you convert between hexadecimal numbers and decimal numbers in C#?
To convert from decimal to hex do...
string hexValue = decValue.ToString("X");
To convert from hex to decimal do either...
int decValue = int.Parse(hexValue, System.Globalization.NumberStyles.HexNumber);
or
int decValue = Convert.ToInt32(hexValue, 16);
Hex -> decimal:
Convert.ToInt64(hexString, 16);
Decimal -> Hex
string.Format("{0:x}", intValue);
It looks like you can say
Convert.ToInt64(value, 16)
to get the decimal from hexdecimal.
The other way around is:
otherVar.ToString("X");
If you want maximum performance when doing conversion from hex to decimal number, you can use the approach with pre-populated table of hex-to-decimal values.
Here is the code that illustrates that idea. My performance tests showed that it can be 20%-40% faster than Convert.ToInt32(...):
class TableConvert
{
static sbyte[] unhex_table =
{ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,-1,-1,-1,-1,-1,-1
,-1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1
,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
,-1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1
,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
};
public static int Convert(string hexNumber)
{
int decValue = unhex_table[(byte)hexNumber[0]];
for (int i = 1; i < hexNumber.Length; i++)
{
decValue *= 16;
decValue += unhex_table[(byte)hexNumber[i]];
}
return decValue;
}
}
From Geekpedia:
// Store integer 182
int decValue = 182;
// Convert integer 182 as a hex in a string variable
string hexValue = decValue.ToString("X");
// Convert the hex string back to the number
int decAgain = int.Parse(hexValue, System.Globalization.NumberStyles.HexNumber);
String stringrep = myintvar.ToString("X");
int num = int.Parse("FF", System.Globalization.NumberStyles.HexNumber);
If it's a really big hex string beyond the capacity of the normal integer:
For .NET 3.5, we can use BouncyCastle's BigInteger class:
String hex = "68c7b05d0000000002f8";
// results in "494809724602834812404472"
String decimal = new Org.BouncyCastle.Math.BigInteger(hex, 16).ToString();
.NET 4.0 has the BigInteger class.
Hex to Decimal Conversion
Convert.ToInt32(number, 16);
Decimal to Hex Conversion
int.Parse(number, System.Globalization.NumberStyles.HexNumber)
For more details Check this article
Try using BigNumber in C# - Represents an arbitrarily large signed integer.
Program
using System.Numerics;
...
var bigNumber = BigInteger.Parse("837593454735734579347547357233757342857087879423437472347757234945743");
Console.WriteLine(bigNumber.ToString("X"));
Output
4F30DC39A5B10A824134D5B18EEA3707AC854EE565414ED2E498DCFDE1A15DA5FEB6074AE248458435BD417F06F674EB29A2CFECF
Possible Exceptions,
ArgumentNullException - value is null.
FormatException - value is not in the correct format.
Conclusion
You can convert string and store a value in BigNumber without constraints about the size of the number unless the string is empty and non-analphabets
static string chex(byte e) // Convert a byte to a string representing that byte in hexadecimal
{
string r = "";
string chars = "0123456789ABCDEF";
r += chars[e >> 4];
return r += chars[e &= 0x0F];
} // Easy enough...
static byte CRAZY_BYTE(string t, int i) // Take a byte, if zero return zero, else throw exception (i=0 means false, i>0 means true)
{
if (i == 0) return 0;
throw new Exception(t);
}
static byte hbyte(string e) // Take 2 characters: these are hex chars, convert it to a byte
{ // WARNING: This code will make small children cry. Rated R.
e = e.ToUpper(); //
string msg = "INVALID CHARS"; // The message that will be thrown if the hex str is invalid
byte[] t = new byte[] // Gets the 2 characters and puts them in seperate entries in a byte array.
{ // This will throw an exception if (e.Length != 2).
(byte)e[CRAZY_BYTE("INVALID LENGTH", e.Length ^ 0x02)],
(byte)e[0x01]
};
for (byte i = 0x00; i < 0x02; i++) // Convert those [ascii] characters to [hexadecimal] characters. Error out if either character is invalid.
{
t[i] -= (byte)((t[i] >= 0x30) ? 0x30 : CRAZY_BYTE(msg, 0x01)); // Check for 0-9
t[i] -= (byte)((!(t[i] < 0x0A)) ? (t[i] >= 0x11 ? 0x07 : CRAZY_BYTE(msg, 0x01)) : 0x00); // Check for A-F
}
return t[0x01] |= t[0x00] <<= 0x04; // The moment of truth.
}
This is not really easiest way but this source code enable you to right any types of octal number i.e 23.214, 23 and 0.512 and so on. Hope this will help you..
public string octal_to_decimal(string m_value)
{
double i, j, x = 0;
Int64 main_value;
int k = 0;
bool pw = true, ch;
int position_pt = m_value.IndexOf(".");
if (position_pt == -1)
{
main_value = Convert.ToInt64(m_value);
ch = false;
}
else
{
main_value = Convert.ToInt64(m_value.Remove(position_pt, m_value.Length - position_pt));
ch = true;
}
while (k <= 1)
{
do
{
i = main_value % 10; // Return Remainder
i = i * Convert.ToDouble(Math.Pow(8, x)); // calculate power
if (pw)
x++;
else
x--;
o_to_d = o_to_d + i; // Saving Required calculated value in main variable
main_value = main_value / 10; // Dividing the main value
}
while (main_value >= 1);
if (ch)
{
k++;
main_value = Convert.ToInt64(Reversestring(m_value.Remove(0, position_pt + 1)));
}
else
k = 2;
pw = false;
x = -1;
}
return (Convert.ToString(o_to_d));
}
This one worked for me:
public static decimal HexToDec(string hex)
{
if (hex.Length % 2 == 1)
hex = "0" + hex;
byte[] raw = new byte[hex.Length / 2];
decimal d = 0;
for (int i = 0; i < raw.Length; i++)
{
raw[i] = Convert.ToByte(hex.Substring(i * 2, 2), 16);
d += Math.Pow(256, (raw.Length - 1 - i)) * raw[i];
}
return d.ToString();
return d;
}
Decimal - Hexa
var decValue = int.Parse(Console.ReadLine());
string hex = string.Format("{0:x}", decValue);
Console.WriteLine(hex);
Hexa - Decimal (use namespace: using System.Globalization;)
var hexval = Console.ReadLine();
int decValue = int.Parse(hexval, NumberStyles.HexNumber);
Console.WriteLine(decValue);
FOUR C# native ways to convert Hex to Dec and back:
using System;
namespace Hexadecimal_and_Decimal
{
internal class Program
{
private static void Main(string[] args)
{
string hex = "4DEAD";
int dec;
// hex to dec:
dec = int.Parse(hex, System.Globalization.NumberStyles.HexNumber);
// or:
dec = Convert.ToInt32(hex, 16);
// dec to hex:
hex = dec.ToString("X"); // lowcase: x, uppercase: X
// or:
hex = string.Format("{0:X}", dec); // lowcase: x, uppercase: X
Console.WriteLine("Hexadecimal number: " + hex);
Console.WriteLine("Decimal number: " + dec);
}
}
}
My version is I think a little more understandable because my C# knowledge is not so high.
I'm using this algorithm: http://easyguyevo.hubpages.com/hub/Convert-Hex-to-Decimal (The Example 2)
using System;
using System.Collections.Generic;
static class Tool
{
public static string DecToHex(int x)
{
string result = "";
while (x != 0)
{
if ((x % 16) < 10)
result = x % 16 + result;
else
{
string temp = "";
switch (x % 16)
{
case 10: temp = "A"; break;
case 11: temp = "B"; break;
case 12: temp = "C"; break;
case 13: temp = "D"; break;
case 14: temp = "E"; break;
case 15: temp = "F"; break;
}
result = temp + result;
}
x /= 16;
}
return result;
}
public static int HexToDec(string x)
{
int result = 0;
int count = x.Length - 1;
for (int i = 0; i < x.Length; i++)
{
int temp = 0;
switch (x[i])
{
case 'A': temp = 10; break;
case 'B': temp = 11; break;
case 'C': temp = 12; break;
case 'D': temp = 13; break;
case 'E': temp = 14; break;
case 'F': temp = 15; break;
default: temp = -48 + (int)x[i]; break; // -48 because of ASCII
}
result += temp * (int)(Math.Pow(16, count));
count--;
}
return result;
}
}
class Program
{
static void Main(string[] args)
{
Console.Write("Enter Decimal value: ");
int decNum = int.Parse(Console.ReadLine());
Console.WriteLine("Dec {0} is hex {1}", decNum, Tool.DecToHex(decNum));
Console.Write("\nEnter Hexadecimal value: ");
string hexNum = Console.ReadLine().ToUpper();
Console.WriteLine("Hex {0} is dec {1}", hexNum, Tool.HexToDec(hexNum));
Console.ReadKey();
}
}
Convert binary to Hex
Convert.ToString(Convert.ToUInt32(binary1, 2), 16).ToUpper()
You can use this code and possible set Hex length and part's:
const int decimal_places = 4;
const int int_places = 4;
static readonly string decimal_places_format = $"X{decimal_places}";
static readonly string int_places_format = $"X{int_places}";
public static string DecimaltoHex(decimal number)
{
var n = (int)Math.Truncate(number);
var f = (int)Math.Truncate((number - n) * ((decimal)Math.Pow(10, decimal_places)));
return $"{string.Format($"{{0:{int_places_format}}}", n)}{string.Format($"{{0:{decimal_places_format}}}", f)}";
}
public static decimal HextoDecimal(string number)
{
var n = number.Substring(0, number.Length - decimal_places);
var f = number.Substring(number.Length - decimal_places);
return decimal.Parse($"{int.Parse(n, System.Globalization.NumberStyles.HexNumber)}.{int.Parse(f, System.Globalization.NumberStyles.HexNumber)}");
}
An extension method for converting a byte array into a hex representation. This pads each byte with leading zeros.
/// <summary>
/// Turns the byte array into its Hex representation.
/// </summary>
public static string ToHex(this byte[] y)
{
StringBuilder sb = new StringBuilder();
foreach (byte b in y)
{
sb.Append(b.ToString("X").PadLeft(2, "0"[0]));
}
return sb.ToString();
}
Here is my function:
using System;
using System.Collections.Generic;
class HexadecimalToDecimal
{
static Dictionary<char, int> hexdecval = new Dictionary<char, int>{
{'0', 0},
{'1', 1},
{'2', 2},
{'3', 3},
{'4', 4},
{'5', 5},
{'6', 6},
{'7', 7},
{'8', 8},
{'9', 9},
{'a', 10},
{'b', 11},
{'c', 12},
{'d', 13},
{'e', 14},
{'f', 15},
};
static decimal HexToDec(string hex)
{
decimal result = 0;
hex = hex.ToLower();
for (int i = 0; i < hex.Length; i++)
{
char valAt = hex[hex.Length - 1 - i];
result += hexdecval[valAt] * (int)Math.Pow(16, i);
}
return result;
}
static void Main()
{
Console.WriteLine("Enter Hexadecimal value");
string hex = Console.ReadLine().Trim();
//string hex = "29A";
Console.WriteLine("Hex {0} is dec {1}", hex, HexToDec(hex));
Console.ReadKey();
}
}
My solution is a bit like back to basics, but it works without using any built-in functions to convert between number systems.
public static string DecToHex(long a)
{
int n = 1;
long b = a;
while (b > 15)
{
b /= 16;
n++;
}
string[] t = new string[n];
int i = 0, j = n - 1;
do
{
if (a % 16 == 10) t[i] = "A";
else if (a % 16 == 11) t[i] = "B";
else if (a % 16 == 12) t[i] = "C";
else if (a % 16 == 13) t[i] = "D";
else if (a % 16 == 14) t[i] = "E";
else if (a % 16 == 15) t[i] = "F";
else t[i] = (a % 16).ToString();
a /= 16;
i++;
}
while ((a * 16) > 15);
string[] r = new string[n];
for (i = 0; i < n; i++)
{
r[i] = t[j];
j--;
}
string res = string.Concat(r);
return res;
}

Categories

Resources