{"id":3106,"date":"2010-07-17T09:29:00","date_gmt":"2010-07-17T09:29:00","guid":{"rendered":"https:\/\/test.simple-talk.com\/uncategorized\/writing-a-byte-array-to-a-hexadecimal-string\/"},"modified":"2017-10-31T13:42:14","modified_gmt":"2017-10-31T13:42:14","slug":"writing-a-byte-array-to-a-hexadecimal-string","status":"publish","type":"post","link":"https:\/\/www.red-gate.com\/simple-talk\/blogs\/writing-a-byte-array-to-a-hexadecimal-string\/","title":{"rendered":"Writing a Byte Array to a Hexadecimal String"},"content":{"rendered":"<p>I was finishing up work on a hashing library and started testing my hash values against other sources to ensure I was doing everything right. Unfortunately, my hashes were off. Long story short, I was converting the hashed byte array into a string using a Base64 string encoder, but what you are supposed to do is convert it into a Hexadecimal string &#8211; that is if you want to conform to standards. I searched around and found out how you are supposed do this from post called <a href=\"http:\/\/stackoverflow.com\/questions\/311165\/how-do-you-convert-byte-array-to-hexadecimal-string-and-vice-versa-in-c\">How do you convert Byte Array to Hexadecimal String, and vice versa, in C#?<\/a> on <a href=\"http:\/\/www.stackoverflow.com\">Stack Overflow<\/a>, as well as a post from <a href=\"https:\/\/msdn.microsoft.com\/en-us\/\">MSDN<\/a> entitled <a href=\"https:\/\/social.msdn.microsoft.com\/Forums\/vstudio\/en-US\/3928b8cb-3703-4672-8ccd-33718148d1e3\/byte-array-to-hex-string?forum=csharpgeneral\">byte[] Array to Hex String<\/a>. In the first post, two options are presented, but no information about which way is faster or why to do one way over the other. So I decided to find out myself because if I have the option, I&#8217;d prefer my code to be faster.<\/p>\n<p><strong>Option 1: Building the hex string using a for loop <br \/>\n<\/strong>In my meanders looking for a solution to the MD5 hash, this is the algorithm that I ran into the most. The method simply runs through each byte in the byte array and outputs the text based version using standard string formatting with a StringBuilder.<\/p>\n<p><code>public static string CreateHexString(byte[] data)     <br \/>\n{      <br \/>\n  StringBuilder hex = new StringBuilder(data.Length * 2);      <br \/>\n  foreach (byte b in data)      <br \/>\n  {      <br \/>\n    hex.AppendFormat(\"{0:x2}\", b);      <br \/>\n  }      <br \/>\n  return hex.ToString();      <br \/>\n}<\/code><\/p>\n<p><strong>Option 2: Using the bit converter and replacing the delimiters <br \/>\n<\/strong>The second option uses the BitConverter class to create a string &#8211; but the string that gets created is delimited by a series of dashes that must subsequently be removed. This is some very succinct code.<\/p>\n<pre>public static string CreateHexString(byte[] data){  return BitConverter.ToString(data).Replace(\"-\",\"\");}<\/pre>\n<p><strong>Option 3: Dark Magic <br \/>\n<\/strong>This piece of code from PZahra from the MSDN link uses right shifting and dark magic that culminates in a hexadecimal string. I modified it slightly from the original code so it would match the strings produced by the other hexadecimal methods.<\/p>\n<p>public static string CreateHexString(byte[] data) <br \/>\n{ <br \/>\n char[] c = new char[data.Length * 2]; <br \/>\n byte b; <br \/>\n for (int y = 0, x = 0; y &lt; data.Length; ++y, ++x) <br \/>\n { <br \/>\n b = ((byte)(data[y] &gt;&gt; 4)); <br \/>\n c[x] = (char)(b &gt; 9 ? b + 0x37 : b + 0x30); <br \/>\n b = ((byte)(data[y] &amp; 0xF)); <br \/>\n c[++x] = (char)(b &gt; 9 ? b + 0x37 : b + 0x30); <br \/>\n } <br \/>\n}<\/p>\n<p>Using my performance timer from a <a href=\"https:\/\/www.simple-talk.com\/community\/blogs\/damon_armstrong\/archive\/2007\/08\/24\/35357.aspx\">previous post<\/a> (though it&#8217;s been slightly modified since then) I ran both options through a series of tests and determined the following:<\/p>\n<p><strong>Option 1<\/strong> runs approximately 40,000 ops\/sec <br \/>\n<strong>Option 2<\/strong> runs approximately 282,000 ops\/sec <br \/>\n<strong>Option 3<\/strong> runs approximately 304,000 ops\/sec<\/p>\n<p>So, using the for-loop is the slowest possible way of doing things, which I find interesting because it seems to be widely used for this purpose. Opting for the BitConverter is more than 7 times faster than the for loop (at least on my system) and it only takes a single line of code to write. Perhaps the BitConverter is a bit obscure (pun definitely intended) so nobody uses it. And if you don&#8217;t mind losing a lot of readability, then you can eek out even more performance using PZahra&#8217;s code.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I was finishing up work on a hashing library and started testing my hash values against other sources to ensure I was doing everything right. Unfortunately, my hashes were off. Long story short, I was converting the hashed byte array into a string using a Base64 string encoder, but what you are supposed to do&#8230;&hellip;<\/p>\n","protected":false},"author":46738,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[2],"tags":[],"coauthors":[7575],"class_list":["post-3106","post","type-post","status-publish","format-standard","hentry","category-blogs"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/3106","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/users\/46738"}],"replies":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/comments?post=3106"}],"version-history":[{"count":3,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/3106\/revisions"}],"predecessor-version":[{"id":75378,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/3106\/revisions\/75378"}],"wp:attachment":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media?parent=3106"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/categories?post=3106"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/tags?post=3106"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/coauthors?post=3106"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}