Better way of generating an alphanumeric 50 char long GUID - c#

I am generating 2 GUIDs and taking the first 50 chars from them. What is the better way of doing this -
string tr1 = string.Join("", Guid.NewGuid().ToString("n"));
string tr2 = string.Join("", Guid.NewGuid().ToString("n"));
string full = ( tr1 + "#" + tr2).Left(50);

This isn't what you asked for, but I think it's what you want:
using System.Security.Cryptography;
public static string Get50RandomHexNybls()
{
var bytes = new byte[25];
var rand = new RNGCryptoServiceProvider();
rand.GetBytes(bytes);
return BitConverter.ToString(bytes).Replace("-", string.Empty);
}
The result looks like:
B7EB8387438D55CAEC2C9D4EE73E8B99BB146EEDA4F8A9CB48
with a different result each time. If you don't like how I converted the bytes to a hex string, take a look at "How do you convert a byte array to a hexadecimal string, and vice versa"

Related

C# ByteString to ASCII String

I am looking for a smart way to convert a string of hex-byte-values into a string of 'real text' (ASCII Characters).
For example I have the word "Hello" written in Hexadecimal ASCII: 48 45 4C 4C 4F. And using some method I want to receive the ASCII text of it (in this case "Hello").
// I have this string (example: "Hello") and want to convert it to "Hello".
string strHexa = "48454C4C4F";
// I want to convert the strHexa to an ASCII string.
string strResult = ConvertToASCII(strHexa);
I am sure there is a framework method. If this is not the case of course I could implement my own method.
Thanks!
var str = Encoding.UTF8.GetString(SoapHexBinary.Parse("48454C4C4F").Value); //HELLO
PS: SoapHexBinary is in System.Runtime.Remoting.Metadata.W3cXsd2001 namespace
I am sure there is a framework method.
A a single framework method: No.
However the second part of this: converting a byte array containing ASCII encoded text into a .NET string (which is UTF-16 encoded Unicode) does exist: System.Text.ASCIIEncoding and specifically the method GetString:
string result = ASCIIEncoding.GetString(byteArray);
The First part is easy enough to do yourself: take two hex digits at a time, parse as hex and cast to a byte to store in the array. Seomthing like:
byte[] HexStringToByteArray(string input) {
Debug.Assert(input.Length % 2 == 0, "Must have two digits per byte");
var res = new byte[input.Length/2];
for (var i = 0; i < input.Length/2; i++) {
var h = input.Substring(i*2, 2);
res[i] = Convert.ToByte(h, 16);
}
return res;
}
Edit: Note: L.B.'s answer identifies a method in .NET that will do the first part more easily: this is a better approach that writing it yourself (while in a, perhaps, obscure namespace it is implemented in mscorlib rather than needing an additional reference).
StringBuilder sb = new StringBuilder();
for (int i = 0; i < hexStr.Length; i += 2)
{
string hs = hexStr.Substring(i, 2);
sb.Append(Convert.ToByte(hs, 16));
}

Convert stringbinary to ascii

i'm just started dev-ing app for wp7 and I'm trying to convert a string of binary back to ascii using c#.
But i have no idea how can it be done.
Hope someone could help me out here.
example :
Input string: 0110100001100101011011000110110001101111
Output string: hello
The simple solution,
using SubString and built in Convert.ToByte could look like this:
string input = "0110100001100101011011000110110001101111";
int charCount = input.Length / 8;
var bytes = from idx in Enumerable.Range(0, charCount)
let str = input.Substring(idx*8,8)
select Convert.ToByte(str,2);
string result = Encoding.ASCII.GetString(bytes.ToArray());
Console.WriteLine(result);
Another solution, doing the calculations yourself:
I added this in case you wanted to know how the calculations should be performed, rather than which method in the framework does it for you:
string input = "0110100001100101011011000110110001101111";
var chars = input.Select((ch,idx) => new { ch, idx});
var parts = from x in chars
group x by x.idx / 8 into g
select g.Select(x => x.ch).ToArray();
var bytes = parts.Select(BitCharsToByte).ToArray();
Console.WriteLine(Encoding.ASCII.GetString(bytes));
Where BitCharsToByte does the conversion from a char[] to the corresponding byte:
byte BitCharsToByte(char[] bits)
{
int result = 0;
int m = 1;
for(int i = bits.Length - 1 ; i >= 0 ; i--)
{
result += m * (bits[i] - '0');
m*=2;
}
return (byte)result;
}
Both the above solutions does basically the same thing: First group the characters in groups of 8; then take that sub string, get the bits represented and calculate the byte value. Then use the ASCII Encoding to convert those bytes to a string.
You can use the BitArray Class and use its CopyTo function to copy ur bit string to byte array
Then you can convert your byte array to string using Text.Encoding.UTF8.GetString(Byte[])
See this link on BitArray on MSDN

Regex Match string with non-alphanumberic chars from a binary file

I am trying to extract some information from a binary file. It looks like this:
AUTHCODE(here goes 3 bytes, that I don't need)part_that_i_need(here goes a NULL byte).
How to I match the portion of alpha-numeric characters qszjlbnkmctkkezgd_qyzkyptqigudilzpkp_qgetefvmigwimrihudk that is between bytes {11} {00} {38} and {00}.
Here's what I've done so far:
string ReadFileMF;
using (StreamReader reader = new StreamReader(pathCopy))
{
ReadFileMF = reader.ReadToEnd();
}
///match the whole string
Match passMF = Regex.Match(ReadFileMF, #"(AUTHCODE).+?(www)");
String passMFs = passMF.Value;
//convert to array of bytes
byte[] bpass = StrToByteArray(passMFs);
//replace the 3 bytes after AUTHCODE with spaces
bpass[8] = 0x20;
bpass[9] = 0x20;
bpass[10] = 0x20;
Ok, so now I have just to match the nullbyte at the end. Somthing like (AUTHCODE).+?(NULL_BYTE). Any ideas?
This might be easiest with a few simple for-loops or Copy() actions over the byte data. Too few specs to be exact. Like:
// untested, I could be off-by-1 somewhere
int start = "AUTHCODE".Length + 3;
int end = text.Indexof('\0', start);
string result = text.SubString(start, end-start);
If you do want/need Regex, you'll have to turn it into a string first. Your only safe bet seems to be ASCII encoding.
string text = Encoding.ASCII.GetString(data);
and then (untested)
Regex.Match(text, "AUTHCODE.{3}([^\0x00]+)\0x00);

Convert a byte[] to its string representation in binary

I need to convert a Byte[] to a string which contain a binary number sequence. I cannot use Encoding because it just encodes bytes into characters!
For example, having this array:
new byte[] { 254, 1 };
I want this output:
"1111111000000001"
You can convert any numeric integer primitive to its binary representation as a string with Convert.ToString. Doing this for each byte in your array and concatenating the results is very easy with LINQ:
var input = new byte[] { 254 }; // put as many bytes as you want in here
var result = string.Concat(input.Select(b => Convert.ToString(b, 2)));
Update:
The code above will not produce a result having exactly 8 characters per input byte, and this will make it impossible to know what the input was just by looking at the result. To get exactly 8 chars per byte, a small change is needed:
var result = string.Concat(input.Select(b => Convert.ToString(b, 2).PadLeft(8, '0')));
string StringIWant = BitConverter.ToString(byteData);
But i suggest work with Encoding..
string System.Text.Encoding.UTF8.GetString(byte[])
EDIT: For like 10101011010
From #Quintin Robinson's answer;
StringBuilder sb = new StringBuilder();
foreach (byte b in myByteArray)
sb.Append(b.ToString("X2"));
string hexString = sb.ToString();
Perhaps you can use the BitArray class to accomplish what you are looking for? They have some sample code in the reference which should be pretty easy to convert to what you are looking for.
Will BitConverter.ToString work for you?
byte[] bList = { 0, 1, 2, 3, 4, 5 };
string s1 = BitConverter.ToString(bList);
string s2 = "";
foreach (byte b in bList)
{
s2 += b.ToString();
}
in this case s1 ="01-02-03-04-05"
and s2= "012345"
I don't really get what are you trying to achieve.

How to convert an MD5 hash to a string and use it as a file name

I am taking the MD5 hash of an image file and I want to use the hash as a filename.
How do I convert the hash to a string that is valid filename?
EDIT: toString() just gives "System.Byte[]"
How about this:
string filename = BitConverter.ToString(yourMD5ByteArray);
If you prefer a shorter filename without hyphens then you can just use:
string filename =
BitConverter.ToString(yourMD5ByteArray).Replace("-", string.Empty);
System.Convert.ToBase64String
As a commenter pointed out -- normal base 64 encoding can contain a '/' character, which obivously will be a problem with filenames. However, there are other characters that are usable, such as an underscore - just replace all the '/' with an underscore.
string filename = Convert.ToBase64String(md5HashBytes).Replace("/","_");
Try this:
Guid guid = new Guid(md5HashBytes);
string hashString = guid.ToString("N");
// format: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
string hashString = guid.ToString("D");
// format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
string hashString = guid.ToString("B");
// format: {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}
string hashString = guid.ToString("P");
// format: (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)
This is probably the safest for file names. You always get a hex string and never worry about / or +, etc.
byte[] data = md5Hash.ComputeHash(Encoding.UTF8.GetBytes(inputString));
StringBuilder sBuilder = new StringBuilder();
for (int i = 0; i < data.Length; i++)
{
sBuilder.Append(data[i].ToString("x2"));
}
string hashed = sBuilder.ToString();
Try this:
string Hash = Convert.ToBase64String(MD5.Create().ComputeHash(Encoding.UTF8.GetBytes("sample")));
//input "sample" returns = Xo/5v1W6NQgZnSLphBKb5g==
or
string Hash = BitConverter.ToString(MD5.Create().ComputeHash(Encoding.UTF8.GetBytes("sample")));
//input "sample" returns = 5E-8F-F9-BF-55-BA-35-08-19-9D-22-E9-84-12-9B-E6
Technically using Base64 is bad if this is Windows, filenames are case insensitive (at least in explorers view).. but in base64, 'a' is different to 'A', this means that perhaps unlikely but you end up with even higher rate of collision..
A better alternative is hexadecimal like the bitconverter class, or if you can- use base32 encoding (which after removing the padding from both base64 and base32, and in the case of 128bit, will give you similar length filenames).
Try Base32 hash of MD5. It gives filename-safe case insensitive strings.
string Base32Hash(string input)
{
byte[] buf = MD5.Create().ComputeHash(Encoding.UTF8.GetBytes(input));
return String.Join("", buf.Select(b => "abcdefghijklmonpqrstuvwxyz234567"[b & 0x1F]));
}

Categories

Resources