I want to convert a Byte array as fast as possible to a Hex String.
So through my previous question, I found the following code:
private static readonly uint[] _lookup32 = CreateLookup32();
private static uint[] CreateLookup32()
{
var result = new uint[256];
for (int i = 0; i < 256; i++)
{
string s = i.ToString("X2");
result[i] = ((uint)s[0]) + ((uint)s[1] << 16);
}
return result;
}
private static string ByteArrayToHexViaLookup32(byte[] bytes)
{
var lookup32 = _lookup32;
var result = new char[bytes.Length * 2];
for (int i = 0; i < bytes.Length; i++)
{
var val = lookup32[bytes[i]];
result[2 * i] = (char)val;
result[2 * i + 1] = (char)(val >> 16);
}
return new string(result);
}
This works great but the Issue with it is that the output string looks like this:
output: 0F42000AAD24120024
but i need it like this: 0F 42 00 0A AD 24 12 00 24
As my coding knowledge is kinda meh on "cryptic" looking algorithms I don't know where and how to add code so it would add a blank space between each 2 Bytes - (Hexoutputstring + " ") to it.
I could loop trough the string and add every 2 charackters a blank space but that would hugely increase the amount of time it needs to give me a useful results as appending strings is slow.
Could someone help me with the code above? Thanks you :)
private static string ByteArrayToHexViaLookup32(byte[] bytes)
{
var lookup32 = _lookup32;
var byteCount = bytes.Length;
var result = new char[3* byteCount - 1];
for (int i = 0; i < byteCount; i++)
{
var val = lookup32[bytes[i]];
int index = 3 * i;
result[index] = (char)val;
result[index + 1] = (char)(val >> 16);
if (i < byteCount - 1) result[index + 2] = ' ';
}
return new string(result);
}
If performance is one of your main concerns, I would approach it something like this:
private static readonly char[] digits = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
private static string ByteArrayToHexViaLookup32(byte[] bytes)
{
char[] buffer = new char[bytes.Length * 3];
int index = 0;
for (int i = 0; i < bytes.Length; i++)
{
if (index > 0)
buffer[index++] = ' ';
buffer[index++] = digits[(bytes[i] >> 4) & 0xf];
buffer[index++] = digits[bytes[i] & 0xf];
}
return new string(buffer, 0, index);
}
The following version doesn't require any lookup array, but I'm not sure if it's as fast.
private static string ByteArrayToHexViaLookup32(byte[] bytes)
{
char[] buffer = new char[bytes.Length * 3];
int index = 0;
for (int i = 0; i < bytes.Length; i++)
{
if (index > 0)
buffer[index++] = ' ';
buffer[index++] = GetDigit((bytes[i] >> 4) & 0xf);
buffer[index++] = GetDigit(bytes[i] & 0xf);
}
return new string(buffer, 0, index);
}
private char GetDigit(int value)
{
if (value < 10)
return (char)('0' + value);
return (char)('7' + value);
}
Both versions insert a space between bytes.
private static string ByteArrayToStringHex(byte[] bytes)
{
string hexValue = BitConverter.ToString(bytes);
hexValue = hexValue.Replace("-", " ");
return hexValue;
}
I think it results the same values as which you want
Related
Right now I try to write a C# Program to translate 8 Base Binary into Text.
But I guess I am not experienced enough with C# to truly make it Work.
I think the code I come up with, should, from a logical Point-of-View somewhat do what I want, but the Syntax isn't properly doing it, since donĀ“t know it better.
This is what I have so far:
using System;
using System.Linq;
using System.Text;
class binaryTranslate
{
public int convertBin(string CodeInput)
{
int [] code = CodeInput.ToArray();
int CodeCount = code.ToString().Length;
int EightBaseSegAmount = CodeCount / 8;
int ByteCapacity = 8;
StringBuilder translated = new StringBuilder();
for (var i = 1; i < EightBaseSegAmount + 1; i++)
{
StringBuilder Byte = new StringBuilder(ByteCapacity);
int ByteStart = (i * 8) - 8;
int ByteEnd = (i * 8) - 1;
int ByteIncrement = 1;
for (var j = ByteStart ; j < ByteEnd + 1; j++)
{
Byte.Append(code[j]);
}
for (var k = 0; k > 7; k++)
{
int BitValue = 128;
if (Byte[k] == 1)
{
if (k > 0)
{
int Squared = Math.Pow(2, k);
ByteIncrement += BitValue / Squared;
}
else
{
ByteIncrement += BitValue;
}
}
}
char toSymbol = Convert.ToChar(ByteIncrement);
translated.Append(toSymbol);
}
return translated;
}
public static int Main()
{
convertBin("010010000110000101101100011011000110111100100001");
}
}
First of all, your code won't compile. Here are the errors/mistakes.
The first one is, at the first line of your function, you are converting the input string to an array using String.ToArray(), which returns a char[] but your try to assign it to a variable (code) typed int[]. You can solve this by replacing the int[] with either char[] or var.
The second one is, inside the second for loop (k = 0; k > 7), you use Math.Pow() and assign it's return value to an int variable (Squared). But Math.Pow returns double. You can solve this by casting the return value of Math.Pow to int. Like; int Squared = (int)Math.Pow(2, k);
The last thing is not easily solvable like the first two because, your code is not exactly correct. You are trying to return something called translated, which is a variable of type StringBuilder. But your function is defined to return an int.
Now these were compile errors. There are a bunch of logical and decision errors/mistakes. Your algorithm also isn't very correct.
Here is a sample code you can use/examine. I'd like to help you further, why your code was incorrect, what was your design mistakes etc. if you want to.
class binaryTranslate
{
public enum IncompleteSegmentBehavior
{
Skip = 0,
ZerosToStart = 1,
ZerosToEnd = 2
}
private byte ConvertBinstrToByte(string sequence)
{
if (string.IsNullOrEmpty(sequence))
return 0; // Throw?
if (sequence.Length != sizeof(byte) * 8)
return 0; // Throw?
const char zero = '0';
const char one = '1';
byte value = 0;
for (int i = 0; i < sequence.Length; i++)
{
if (sequence[i] != zero && sequence[i] != one)
return 0; // Throw
value |= (byte)((sequence[i] - zero) << (7 - i));
}
return value;
}
private string HandleIncompleteSegment(string segment, int segmentSize, IncompleteSegmentBehavior behavior)
{
string result = null;
var zeroAppender = new StringBuilder();
for (int i = 0; i < segmentSize - segment.Length; i++)
zeroAppender.Append('0');
var zeros = zeroAppender.ToString();
switch (behavior)
{
case IncompleteSegmentBehavior.Skip:
break;
case IncompleteSegmentBehavior.ZerosToStart:
result = zeros + result;
break;
case IncompleteSegmentBehavior.ZerosToEnd:
result = result + zeros;
break;
default:
break;
}
return result;
}
public byte[] ConvertBinstrToBytes(string binarySequence, IncompleteSegmentBehavior behavior = IncompleteSegmentBehavior.Skip)
{
var segmentSize = sizeof(byte) * 8;
var sequenceLength = binarySequence.Length;
var numberOfBytes = (int)Math.Ceiling((double)sequenceLength / segmentSize);
var bytes = new byte[numberOfBytes];
for (int i = 0; i < numberOfBytes; i++)
{
var charactersLeft = sequenceLength - i * segmentSize;
var segmentLength = (charactersLeft < segmentSize ? charactersLeft : segmentSize);
var segment = binarySequence.Substring(i * segmentSize, segmentLength);
if (charactersLeft < segmentSize)
{
segment = HandleIncompleteSegment(segment, segmentSize, behavior);
if (segment == null)
continue;
}
bytes[i] = ConvertBinstrToByte(segment);
}
return bytes;
}
}
This code passes these assertions.
var bytes = new binaryTranslate()
.ConvertBinstrToBytes("00000000");
Assert.Equal(bytes.Length, 1);
Assert.Equal(bytes[0], 0b00000000);
bytes = new binaryTranslate()
.ConvertBinstrToBytes("10000000");
Assert.Equal(bytes.Length, 1);
Assert.Equal(bytes[0], 0b10000000);
bytes = new binaryTranslate()
.ConvertBinstrToBytes("11111111");
Assert.Equal(bytes.Length, 1);
Assert.Equal(bytes[0], 0b11111111);
bytes = new binaryTranslate()
.ConvertBinstrToBytes("00000001");
Assert.Equal(bytes.Length, 1);
Assert.Equal(bytes[0], 0b00000001);
bytes = new binaryTranslate()
.ConvertBinstrToBytes("1100110000110011");
Assert.Equal(bytes.Length, 2);
Assert.Equal(bytes[0], 0b11001100);
Assert.Equal(bytes[1], 0b00110011);
If you are really converting to a string the code should look like this
namespace binaryTranslate
{
class Program
{
static void Main(string[] args)
{
//convertBin("01001000 01100001 01101100 01101100 01101111 00100001");
string results = BinaryTranslate.convertBin(new byte[] { 0x44, 0x61, 0x6c, 0x6c, 0x6f, 0x21 });
}
}
public class BinaryTranslate
{
public static string convertBin(byte[] CodeInput)
{
return string.Join("", CodeInput.Select(x => x.ToString("X2")));
}
}
}
this should do the trick.
public static string FromBinary(string binary)
{
int WordLength = 8;
binary = binary.Replace(' ', '');
while(binary.Length % WordLength != 0)
binary += "0";
string output = String.Empty;
string word = String.Empty;
int offset = 0;
while(offset < binary.Length)
{
int tmp = 0;
word = binary.Substring(offset, 8);
for(int i=0; i<(WordLength - 1); i++)
if(word[i] == '1')
tmp += (int) Math.Pow(2, i);
output += Convert.ToChar(tmp);
offset += WordLength;
}
return output;
}
I wonder if anyone could help me out here. I'm trying to do a brute-force algorithm that will follow a specific pattern.
I can make it output the pattern with some sloppy code work but this stuff is kind of new to me. I have really no idea how to go on from here. If you have an idea how I could do this, I would really apreciate it.
The pattern looks like this
AA0AA0A0
So I want it to bruteforce from AA0AA0A0 and up to AA9AA9A9 then will it go to AA0AA0B0
I would highly appreciate all suggestions. I have tried to google some solution, but not really found anything special.
Explanation of the process:
Starts with generating the first string AA0AA0A0.
Then it generates all the way up to AA0AA0A9.
Then it start with the next number so it would be AA0AA1A0.
So it will count up all the way to AA9AA9AA9 which would result it to jump to AA0AA0B0.
Also updated the code so it's working now.
private static char[] fCharList = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' };
private static char[] fNumList = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
static void Main(string[] args)
{
StartBruteForce(8);
}
public static void StartBruteForce(int length)
{
StringBuilder sb = new StringBuilder(length);
char currentChar = fCharList[0];
char currentNum = fNumList[0];
for (int i = 1; i <= 2; i++)
{
sb.Append(currentChar);
}
for (int i = 1; i <= 1; i++)
{
sb.Append(currentNum);
}
for (int i = 1; i <= 2; i++)
{
sb.Append(currentChar);
}
for (int i = 1; i <= 1; i++)
{
sb.Append(currentNum);
}
for (int i = 1; i <= 2; i++)
{
sb.Append(currentChar);
}
for (int i = 2; i <= 1; i++)
{
sb.Append(currentNum);
}
//Console.WriteLine(sb);
//Console.ReadLine();
ChangeCharacters(7, sb, length);
}
private static StringBuilder ChangeCharacters(int pos, StringBuilder sb, int length)
{
for (int i = 0; i <= sb.Length - 1; i++)
{
//sb.setCharAt(pos, fCharList[i]);
sb.Replace(sb[pos], fNumList[i], pos, 1);
//sb.Replace(sb[pos], fCharList[i], pos, 1);
if (pos == length - 1)
{
// Write the Brute Force generated word.
Console.WriteLine(sb.ToString());
Console.ReadLine();
}
else
{
ChangeCharacters(pos - 1, sb, length);
}
}
return sb;
}
Yet another alternative solution:
var results = from a0 in charList
from a1 in charList
from a2 in charList
from a3 in charList
from a4 in charList
from a5 in numList
from a6 in numList
from a7 in numList
select "" + a0 + a1 + a5 + a2 + a3 + a6 + a4 + a7;
Again, a nice one-statement solution thanks to LINQ.
Start by reading my article on how to compute a Cartesian product:
https://blogs.msdn.microsoft.com/ericlippert/2010/06/28/computing-a-cartesian-product-with-linq/
Now it should be clear how to proceed:
var results = from product in CartesianProduct(
new[] { charList, charList, charList, charList, charList, numList, numList, numList } )
let a = product.ToArray()
select "" + a[0] + a[1] + a[5] + a[2] + a[3] + a[6] + a[4] + a[7];
Behold the power of LINQ: solving your combinatorics problems in a single statement.
I think the easiest way to do this is to split the pattern in two; one for the digits, and one for the chars. The digits progress from 000 to 999, and the chars from AAAAA to ZZZZZ. You then just have to splice the digits into the right places of the chars.
IEnumerable<string> Strings()
{
var digits = new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
var chars = Enumerable.Range((int)'A', (int)'Z' - (int)'A' + 1).Select(i => (char)i).ToArray();
for (var c = 0L; c < Math.Pow(chars.Length, 5); ++c)
{
var cstr = chars[(c / (chars.Length * chars.Length * chars.Length * chars.Length) % chars.Length)].ToString()
+ chars[(c / (chars.Length * chars.Length * chars.Length) % chars.Length)]
+ chars[(c / (chars.Length * chars.Length) % chars.Length)]
+ chars[(c / (chars.Length) % chars.Length)]
+ chars[(c % chars.Length)];
for (var i = 0L; i < 999; ++i)
{
var istr = (i / 100 % 10).ToString()
+ (i / 10 % 10).ToString()
+ (i % 10).ToString();
var str = cstr.Substring(0, 2) + istr.Substring(0, 1) + cstr.Substring(2, 2) + istr.Substring(1, 1) + cstr.Substring(4, 1) + istr.Substring(2, 1);
yield return str;
}
}
}
Using it it like this:
var early = Strings().Take(15);
var late = Strings().Skip(1234).Take(15);
foreach (var s in early.Concat(late))
{
Console.WriteLine(s);
}
will print this:
AA0AA0A0
AA0AA0A1
AA0AA0A2
AA0AA0A3
AA0AA0A4
AA0AA0A5
AA0AA0A6
AA0AA0A7
AA0AA0A8
AA0AA0A9
AA0AA1A0
AA0AA1A1
AA0AA1A2
AA0AA1A3
AA0AA1A4
AA2AA3B5
AA2AA3B6
AA2AA3B7
AA2AA3B8
AA2AA3B9
AA2AA4B0
AA2AA4B1
AA2AA4B2
AA2AA4B3
AA2AA4B4
AA2AA4B5
AA2AA4B6
AA2AA4B7
AA2AA4B8
AA2AA4B9
I think it would be better if you have a function that returns the next "pattern" string, so you can have a single for loop.
Something like this:
public static string Next(string pattern)
{
bool carry = true;
var sb = new List<char>();
int t;
for(int i = pattern.Length - 1; i >= 0; i--)
{
if (!carry)
{
sb.Insert(0, pattern[i]);
continue;
}
if (char.IsDigit(pattern[i]))
{
t = int.Parse(pattern[i].ToString()) + 1;
if (t == 10)
{
sb.Insert(0, '0');
carry = true;
}
else
{
sb.Insert(0, t.ToString()[0]);
carry = false;
}
}
else
{
t = (int)pattern[i] + 1;
if (t == 91)
{
sb.Insert(0, 'A');
carry = true;
}
else
{
sb.Insert(0, Convert.ToChar(t));
carry = false;
}
}
}
return new string(sb.ToArray());
}
Check the .Net Fiddle
Some simple loops will iterate over and build a new string each time. you can convert chars to int and back. So you can treat each letter as a number. This assumes your pattern is always AA0AA0A0. If that changes you would need to make the program smarter.
static void Main(string[] args)
{
foreach (var results in BruteForce())
{
Console.WriteLine(results);
}
}
public static IEnumerable<String> BruteForce()
{
const int firstLetter = 'A';
const int lastLetter = 'Z';
for (var firstPos = firstLetter; firstPos <= lastLetter; firstPos++)
{
for (var secondPos = firstLetter; secondPos <= lastLetter; secondPos++)
{
for (var thirdPos = 0; thirdPos <= 9; thirdPos++)
{
for (var fourthPos = firstLetter; fourthPos <= lastLetter; fourthPos++)
{
for (var fifthPos = firstLetter; fifthPos <= lastLetter; fifthPos++)
{
for (var sixthPos = 0; sixthPos <= 9; sixthPos++)
{
for (var sevethPos = firstLetter; sevethPos <= lastLetter; sevethPos++)
{
for (var eighthPos = 0; eighthPos <= 9; eighthPos++)
{
yield return
String.Join(string.Empty,
(char) firstPos,
(char) secondPos,
thirdPos,
(char) fourthPos,
(char) fifthPos,
sixthPos,
(char) sevethPos,
eighthPos);
}
}
}
}
}
}
}
}
}
public static IEnumerable<String> loop()
{
char[] chars = new char[] { 'a', 'b', 'c' };
for (int i = 0; i < 3000; i++)
{
string s = string.Format("aa{0}aa{1}{2}{3}", (i % 1000) / 100, (i % 100) / 10, chars[(i % 10000) / 1000], i % 10);
System.Diagnostics.Debug.WriteLine(s);
yield s;
}
}
Alternative solution:
Make a counter that goes up from 0 to 10 * 10 * 10 * 26 * 26 * 26 * 26 * 26 - 1. It should be a long.
On each tick of the counter, let the number be c. The bottom digit is '0' + c%10. The next digit is '0' + c/10%10. The next is '0' + c/(10*10)%10. The bottom letter is 'A' + c/(10*10*10)%26. The next letter is 'A' + c/(10*10*10*26)%26. And so on.
Put the letters and digits together in the right order and yield the result.
Turning this into code is left as an exercise.
I have two words,
britanicaeng and
britanicahin
I need to find out the longest common word between these i.e, britanica.
How can I do this in C# ?
Try this method:
public static string FindLongestCommonSubstring(string s1, string s2)
{
int[,] a = new int[s1.Length + 1, s2.Length + 1];
int row = 0; // s1 index
int col = 0; // s2 index
for (var i = 0; i < s1.Length; i++)
for (var j = 0; j < s2.Length; j++)
if (s1[i] == s2[j])
{
int len = a[i + 1, j + 1] = a[i, j] + 1;
if (len > a[row, col])
{
row = i + 1;
col = j + 1;
}
}
return s1.Substring(row - a[row, col], a[row, col]);
}
Usage example:
Console.WriteLine(FindLongestCommonSubstring("britanicaeng", "britanicahin"));
I refactored the C++ code from Ashutosh Singh at https://iq.opengenus.org/longest-common-substring-using-rolling-hash/ to create a rolling hash approach in C# - this will find the substring in O(N * log(N)^2) time and O(N) space
using System;
using System.Collections.Generic;
public class RollingHash
{
private class RollingHashPowers
{
// _mod = prime modulus of polynomial hashing
// any prime number over a billion should suffice
internal const int _mod = (int)1e9 + 123;
// _hashBase = base (point of hashing)
// this should be a prime number larger than the number of characters used
// in my use case I am only interested in ASCII (256) characters
// for strings in languages using non-latin characters, this should be much larger
internal const long _hashBase = 257;
// _pow1 = powers of base modulo mod
internal readonly List<int> _pow1 = new List<int> { 1 };
// _pow2 = powers of base modulo 2^64
internal readonly List<long> _pow2 = new List<long> { 1L };
internal void EnsureLength(int length)
{
if (_pow1.Capacity < length)
{
_pow1.Capacity = _pow2.Capacity = length;
}
for (int currentIndx = _pow1.Count - 1; currentIndx < length; ++currentIndx)
{
_pow1.Add((int)(_pow1[currentIndx] * _hashBase % _mod));
_pow2.Add(_pow2[currentIndx] * _hashBase);
}
}
}
private class RollingHashedString
{
readonly RollingHashPowers _pows;
readonly int[] _pref1; // Hash on prefix modulo mod
readonly long[] _pref2; // Hash on prefix modulo 2^64
// Constructor from string:
internal RollingHashedString(RollingHashPowers pows, string s, bool caseInsensitive = false)
{
_pows = pows;
_pref1 = new int[s.Length + 1];
_pref2 = new long[s.Length + 1];
const long capAVal = 'A';
const long capZVal = 'Z';
const long aADif = 'a' - 'A';
unsafe
{
fixed (char* c = s)
{
// Fill arrays with polynomial hashes on prefix
for (int i = 0; i < s.Length; ++i)
{
long v = c[i];
if (caseInsensitive && capAVal <= v && v <= capZVal)
{
v += aADif;
}
_pref1[i + 1] = (int)((_pref1[i] + v * _pows._pow1[i]) % RollingHashPowers._mod);
_pref2[i + 1] = _pref2[i] + v * _pows._pow2[i];
}
}
}
}
// Rollingnomial hash of subsequence [pos, pos+len)
// If mxPow != 0, value automatically multiply on base in needed power.
// Finally base ^ mxPow
internal Tuple<int, long> Apply(int pos, int len, int mxPow = 0)
{
int hash1 = _pref1[pos + len] - _pref1[pos];
long hash2 = _pref2[pos + len] - _pref2[pos];
if (hash1 < 0)
{
hash1 += RollingHashPowers._mod;
}
if (mxPow != 0)
{
hash1 = (int)((long)hash1 * _pows._pow1[mxPow - (pos + len - 1)] % RollingHashPowers._mod);
hash2 *= _pows._pow2[mxPow - (pos + len - 1)];
}
return Tuple.Create(hash1, hash2);
}
}
private readonly RollingHashPowers _rhp;
public RollingHash(int longestLength = 0)
{
_rhp = new RollingHashPowers();
if (longestLength > 0)
{
_rhp.EnsureLength(longestLength);
}
}
public string FindCommonSubstring(string a, string b, bool caseInsensitive = false)
{
// Calculate max neede power of base:
int mxPow = Math.Max(a.Length, b.Length);
_rhp.EnsureLength(mxPow);
// Create hashing objects from strings:
RollingHashedString hash_a = new RollingHashedString(_rhp, a, caseInsensitive);
RollingHashedString hash_b = new RollingHashedString(_rhp, b, caseInsensitive);
// Binary search by length of same subsequence:
int pos = -1;
int low = 0;
int minLen = Math.Min(a.Length, b.Length);
int high = minLen + 1;
var tupleCompare = Comparer<Tuple<int, long>>.Default;
while (high - low > 1)
{
int mid = (low + high) / 2;
List<Tuple<int, long>> hashes = new List<Tuple<int, long>>(a.Length - mid + 1);
for (int i = 0; i + mid <= a.Length; ++i)
{
hashes.Add(hash_a.Apply(i, mid, mxPow));
}
hashes.Sort(tupleCompare);
int p = -1;
for (int i = 0; i + mid <= b.Length; ++i)
{
if (hashes.BinarySearch(hash_b.Apply(i, mid, mxPow), tupleCompare) >= 0)
{
p = i;
break;
}
}
if (p >= 0)
{
low = mid;
pos = p;
}
else
{
high = mid;
}
}
// Output answer:
return pos >= 0
? b.Substring(pos, low)
: string.Empty;
}
}
I have the following code in Java:
public static byte[] hex(String hex) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int nexti = 0;
int nextb = 0;
boolean highoc = true;
outer:
while (true)
{
int number = -1;
while (number == -1) {
if (nexti == hex.length()) {
break outer;
}
char chr = hex.charAt(nexti);
if ((chr >= '0') && (chr <= '9'))
number = chr - '0';
else if ((chr >= 'a') && (chr <= 'f'))
number = chr - 'a' + 10;
else if ((chr >= 'A') && (chr <= 'F'))
number = chr - 'A' + 10;
else {
number = -1;
}
nexti++;
}
if (highoc) {
nextb = number << 4;
highoc = false;
} else {
nextb |= number;
highoc = true;
baos.write(nextb);
}
}
label161: return baos.toByteArray();
}
I'm trying to convert it to C#, and failing, because MemoryStream is the only option, and I don't have a buffer.
This is what I have now:
public static byte[] fromString(string hex)
{
MemoryStream baos = new MemoryStream();
int nexti = 0;
int nextb = 0;
bool highoc = true;
for (; ; )
{
int number = -1;
while (number == -1)
{
if (nexti == hex.Length)
{
goto END;
}
char chr = hex.ToCharArray()[nexti];
if (chr >= '0' && chr <= '9')
{
number = chr - '0';
}
else if (chr >= 'a' && chr <= 'f')
{
number = chr - 'a' + 10;
}
else if (chr >= 'A' && chr <= 'F')
{
number = chr - 'A' + 10;
}
else
{
number = -1;
}
nexti++;
}
if (highoc)
{
nextb = number << 4;
highoc = false;
}
else
{
nextb |= number;
highoc = true;
baos.Write(nextb);
}
}
END:
return baos.toByteArray();
}
What else can I do to make it work like the way in Java?.. Thanks.
Here is something similar
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;
}
public 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));
}
or
public static byte[] StringToByteArray(String hex)
{
int NumberChars = hex.Length;
byte[] bytes = new byte[NumberChars / 2];
for (int i = 0; i < NumberChars; i += 2)
bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16);
return bytes;
}
or
private byte[] HexStringToByteArray(string hexString)
{
int hexStringLength = hexString.Length;
byte[] b = new byte[hexStringLength / 2];
for (int i = 0; i < hexStringLength; i += 2)
{
int topChar = (hexString[i] > 0x40 ? hexString[i] - 0x37 : hexString[i] - 0x30) << 4;
int bottomChar = hexString[i + 1] > 0x40 ? hexString[i + 1] - 0x37 : hexString[i + 1] - 0x30;
b[i / 2] = Convert.ToByte(topChar + bottomChar);
}
return b;
}
Here is alot more of them.
How do you convert Byte Array to Hexadecimal String, and vice versa?
I have a string value that its length is 5000 + characters long , i want to split this into 76 characters long with a new line at the end of each 76 characters. how woudld i do this in c#?
If you're writing Base64 data, try writing
Convert.ToBase64String(bytes, Base64FormattingOptions.InsertLineBreaks);
This will insert a newline every 76 characters
A side on this, if you want StringBuilder versus string performance the best article is the codeproject one found here.
(This doesn't show string size however)
In a nutshell, StringBuilder isn't faster until a threshold is met with the string length (or repeated contactenation), which you're well under, so stick the regular string concatenation and String methods.
Try this:
s = Regex.Replace(s, #"(?<=\G.{76})", "\r\n");
EDIT: Apparently, this is the slowest method of all those posted so far. I wonder how it does if you pre-compile the regex:
Regex rx0 = new Regex(#"(?<=\G.{76})");
s = rx0.Replace(s, "\r\n"); // only time this portion
Also, how does it compare to a straight matching approach?
Regex rx1 = new Regex(".{76}");
s = rx1.Replace(s, "$0\r\n"); // only time this portion
I've always wondered how expensive those unbounded lookbehinds are.
A little uglier ... but much faster ;) (this version took 161 ticks... Aric's took 413)
I posted my test code on my blog. http://hackersbasement.com/?p=134
(I also found StringBuilder to be much slower than string.Join)
http://hackersbasement.com/?p=139 <= updated results
string chopMe = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
Stopwatch sw = new Stopwatch();
sw.Start();
char[] chopMeArray = chopMe.ToCharArray();
int totalLength = chopMe.Length;
int partLength = 12;
int partCount = (totalLength / partLength) + ((totalLength % partLength == 0) ? 0 : 1);
int posIndex = 0;
char[] part = new char[partLength];
string[] parts = new string[partCount];
int get = partLength;
for (int i = 0; i < partCount; i++)
{
get = Math.Min(partLength, totalLength - posIndex);
Array.Copy(chopMeArray, posIndex, part, 0, get);
parts[i] = new string(part, 0, get);
posIndex += partLength;
}
var output = string.Join("\r\n", parts) + "\r\n";
sw.Stop();
Console.WriteLine(sw.ElapsedTicks);
public static string InsertNewLine(string s, int len)
{
StringBuilder sb = new StringBuilder(s.Length + (int)(s.Length/len) + 1);
int start = 0;
for (start=0; start<s.Length-len; start+=len)
{
sb.Append(s.Substring(start, len));
sb.Append(Environment.NewLine);
}
sb.Append(s.Substring(start));
return sb.ToString();
}
where s would be your input string and len the desired line length (76).
string[] FixedSplit(string s, int len)
{
List<string> output;
while (s.Length > len)
{
output.Add(s.Substring(0, len) + "\n");
s.Remove(0, len);
}
output.Add(s + "\n");
return output.ToArray();
}
public static IEnumerable<string> SplitString(string s, int length)
{
var buf = new char[length];
using (var rdr = new StringReader(s))
{
int l;
l = rdr.ReadBlock(buf, 0, length);
while (l > 0)
{
yield return (new string(buf, 0, l)) + Environment.NewLine;
l = rdr.ReadBlock(buf, 0, length);
}
}
}
Then to put them back together:
string theString = GetLongString();
StringBuilder buf = new StringBuilder(theString.Length + theString.Length/76);
foreach (string s in SplitString(theString, 76) { buf.Append(s); }
string result = buf.ToString();
Or you could do this:
string InsertNewLines(string s, int interval)
{
char[] buf = new char[s.Length + (int)Math.Ceiling(s.Length / (double)interval)];
using (var rdr = new StringReader(s))
{
for (int i=0; i<buf.Length-interval; i++)
{
rdr.ReadBlock(buf, i, interval);
i+=interval;
buf[i] = '\n';
}
if (i < s.Length)
{
rdr.ReadBlock(buf, i, s.Length - i);
buf[buf.Length - 1] = '\n';
}
}
return new string(buf);
}
One more.... (first time through slowish, subsequent runs, similar to the faster times posted above)
private void button1_Click(object sender, EventArgs e)
{
string chopMe = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
Stopwatch sw = new Stopwatch();
sw.Start();
string result = string.Join("\r\n", ChopString(chopMe).ToArray());
sw.Stop();
MessageBox.Show(result + " " + sw.ToString());
}
public IEnumerable<string> ChopString(string s)
{
int i = 0;
while (i < s.Length)
{
yield return i + PARTLENGTH <= s.Length ? s.Substring(i,PARTLENGTH) :s.Substring(i) ;
i += PARTLENGTH;
}
}
Edit: I was curious to see how fast substring was...
The string is 5000 characters... I don't think speed is really of the essence unless you're doing this thousands or maybe even millions of times, especially when the OP didn't even mention speed being important. Premature optimization?
I would probably use recursion as it will, in my opinion, lead to the simplest code.
This may not be syntatically correct, as I know .NET but not C#.
String ChunkString(String s, Integer chunkLength) {
if (s.Length <= chunkLength) return s;
return String.Concat(s.Substring(0, chunkLength),
ChunkString(s.Substring(chunkLength)));
}
mostly for the fun of it, here's a different solution implemented as extension method to string:
(\r\n used explicitly so will only support that format for newline);
public static string Split(this string str, int len)
{
char org = str.ToCharArray();
int parts = str.Length / len + (str.Length % len == 0 ? 0 : 1);
int stepSize = len + newline.Length;
char[] result = new char[parts * stepSize];
int resLen = result.Length;
for (int i =0;i<resLen ;i+stepSize)
{
Array.Copy(org,i*len,result,i*stepSize);
resLen[i++] = '\r';
resLen[i++] = '\n';
}
return new string(result);
}
In the end, this would be what I would use, I think
static string fredou()
{
string s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
int partLength = 12;
int stringLength = s.Length;
StringBuilder n = new StringBuilder(stringLength + (int)(stringLength / partLength) + 1);
int chopSize = 0;
int pos = 0;
while (pos < stringLength)
{
chopSize = (pos + partLength) < stringLength ? partLength : stringLength - pos;
n.Append(s , pos, chopSize);
n.Append("\r\n");
pos += chopSize;
}
return n.ToString();
}
by looking at AppendLine under reflector:
<ComVisible(False)> _
Public Function AppendLine(ByVal value As String) As StringBuilder
Me.Append(value)
Return Me.Append(Environment.NewLine)
End Function
Public Shared ReadOnly Property NewLine As String
Get
Return ChrW(13) & ChrW(10)
End Get
End Property
For me, speed wise, doing it manually > AppendLine
I'm spliting the string by 35
var tempstore ="12345678901234567890123456789012345";
for (int k = 0; k < tempstore.Length; k += 35)
{
PMSIMTRequest.Append(tempstore.Substring(k, tempstore.Length - k > 35 ? 35 : tempstore.Length - k));
PMSIMTRequest.Append(System.Environment.NewLine);
}
messagebox.Show(PMSIMTRequest.tostring());
#M4N's answer is very good , but I think while statement is easier to understand than for statement.
public static string InsertNewLine(string source, int len = 76)
{
var sb = new StringBuilder(source.Length + (int)(source.Length / len) + 1);
var start = 0;
while ((start + len) < source.Length)
{
sb.Append(source.Substring(start, len));
sb.Append(Environment.NewLine);
start += len;
}
sb.Append(source.Substring(start));
return sb.ToString();
}