none
A little deciphering help RRS feed

  • Question

  • foreach (char c in b.ToCharArray()) { if (c >= '0' && c <= '9') { v *= 16; v += (c - '0'); } else if (c >= 'a' && c <= 'f') { v *= 16; v += (c - 'a' + 10); } else if (c >= 'A' && c <= 'F') { v *= 16; v += (c - 'A' + 10); } }

       I code in VB.net and not C#. I can understand most of C# operations and syntax but this entire bit has me confused. I'd like to convert this to VB but everything I've tried either doesn't produce the correct result or the VB sytax cant adapt to this properly.
       This is part of a larger program, a bitcoin address generator that someone else built in 2010-ish I believe. I got everything else working perfectly except this. Are they subtracting characters from characters? This makes no sense to me. Thanks in advance everyone. 
            

    Tuesday, December 5, 2017 4:38 AM

All replies

  • It's treating each character in the array as an ASCII value.

    If a character is between '0' and '9' it must be a digit from 1 to 9. If we subtract the ASCII of '0' (which is 48 in decimal) then we will get the numeric value of the character. Example '5' - '0' = 53 - 48 = 5.

    It's a similar story for the letters 'a' to 'f' and 'A' to 'F'. Subtracting the ASCII of 'a' or 'A' as appropriate and adding 10 will give the hexadecimal of the letter. Example, 'c' - 'a' + 10 = 99 - 97 + 10 = 12.  (c = 12 in hex).

    Does that help?
    • Marked as answer by Jebtrillion137 Tuesday, December 5, 2017 5:41 AM
    • Unmarked as answer by Jebtrillion137 Tuesday, December 5, 2017 8:26 AM
    Tuesday, December 5, 2017 5:28 AM
  • Yes that is extremely helpful! Let me see if I can now write a work around in vb. the code converters do not work with this particular set of instructions. If you could assist me in that it would be even more helpful. If not, you have already helped so much. 

    Thank you!

    Tuesday, December 5, 2017 5:34 AM
  • No worries for the help thus far, but I don't speak VB, sorry.
    Tuesday, December 5, 2017 5:39 AM
  • So are they removing the letters a, f, A and F?
    Tuesday, December 5, 2017 5:42 AM
  • They are converting each character to a hexadecimal digit (a digit from 0 to 15, where the numbers from 10 to 15 are represented by the letters from 'a' to 'f' and can be capital or lower case) and adding the result to a decimal number, multiplied by the appropriate power of 16.

    Or, to put it another way, they are converting hexadecimal to decimal.

    for example, if the character array is "123abc", v should be...

    (1 * 16 ^5) + (2 * 16 ^4) + (3 * 16 ^3) + (10 * 16 ^ 2) + (11 * 16 ^ 1) + (12 * 16 ^0)

    (Because a = 10, b = 11, c = 12.)
    Tuesday, December 5, 2017 5:54 AM
  • Wouldn't it be simpler with a hard coded table?

    if C = X then V = X?

    The first X being a char and the second, V's X being the appropriate dec value? 
    Tuesday, December 5, 2017 6:53 AM
  • Thoughts?
    Tuesday, December 5, 2017 7:19 AM
  • Unfortunately I still haven't been able to fully understand what I need to do. 
    Tuesday, December 5, 2017 8:27 AM
  •       For Each c As Char In b.ToCharArray
    
                    If ((c >= "0") AndAlso (c <= "9")) Then
                        v = v * 16
                        v = v + (Asc(c) - 48)
                    ElseIf ((c >= "a") AndAlso (c <= "f")) Then
                        v = v * 16
                        v = v + (Asc(c) - 97 + 10)
                    ElseIf ((c >= "A") AndAlso (c <= "F")) Then
                        v = v * 16
                        v = v + (Asc(c) - 65 + 10)
                    End If
    
                Next
    This is what I came up with based off your advice but it doesn't seem to work. See anything wrong? 
    Tuesday, December 5, 2017 9:18 AM
  • or this 

                For Each c As Char In b.ToCharArray
    
                    If (Asc(c) >= 0) AndAlso (Asc(c) <= 9) Then
                        v = v * 16
                        v = v + (Asc(c) - 48)
                    ElseIf (Asc(c) >= 97) AndAlso (Asc(c) <= 102) Then
                        v = v * 16
                        v = v + (Asc(c) - 97 + 10)
                    ElseIf (Asc(c) >= 65) AndAlso (Asc(c) <= 70) Then
                        v = v * 16
                        v = v + (Asc(c) - 65 + 10)
                    End If
    
                Next

    Tuesday, December 5, 2017 9:37 AM
  • Sorry for the delay. I was away from the internet overnight.

    Both those solutions look okay to me, but I don't speak VB. You need to debug through one character at a time to see what it's doing. Perhaps make a little test app where you set the array to, say, "1a" and see if you get 26 as expected.


    • Edited by Ante Meridian Wednesday, December 6, 2017 1:26 AM I can't count. 26 not 170, as expected.
    Tuesday, December 5, 2017 10:28 PM
  • Greetings again.

    I have tried creating a test app using my limited knowledge of VB. It turns out that there is a bug in the second of your proposed solutions (which I can explain if you like), but the first looks okay.

    Specifically, I tried the following VB console application.

    Module Module1
    
       Sub Main()
          Dim b As String = "90f0"
          Dim v As Int32 = 0
          For Each c As Char In b.ToCharArray
    
             If ((c >= "0") AndAlso (c <= "9")) Then
                v = v * 16
                v = v + (Asc(c) - 48)
             ElseIf ((c >= "a") AndAlso (c <= "f")) Then
                v = v * 16
                v = v + (Asc(c) - 97 + 10)
             ElseIf ((c >= "A") AndAlso (c <= "F")) Then
                v = v * 16
                v = v + (Asc(c) - 65 + 10)
             End If
    
          Next
    
          Console.WriteLine("v = " + v.ToString)
       End Sub
    
    End Module

    And compared its output to the following in c#.

    using System;
    
    namespace ConsoleApplication3
    {
       class Program
       {
          public static void Main()
          {
             string b = "90f0";
             int v = 0;
             foreach (char c in b.ToCharArray())
             {
                if (c >= '0' && c <= '9')
                {
                   v *= 16;
                   v += (c - '0');
    
                }
                else if (c >= 'a' && c <= 'f')
                {
                   v *= 16;
                   v += (c - 'a' + 10);
                }
                else if (c >= 'A' && c <= 'F')
                {
                   v *= 16;
                   v += (c - 'A' + 10);
                }
    
             }
    
             Console.WriteLine("v = " + v.ToString());
          }
       }
    }

    They consistently give the same output, no matter what value is set for b. I have tried "123abc", "ABC123", "F0", "99", and a few others, and the result is always a match.

    The only thing I can think that might go wrong is if v is the wrong type. For example, I have assumed it is a 32-bit integer, but if it is only 16 bits it could easily overflow. Or perhaps it should be unsigned instead of signed. But as long as it's the same type in both cases, your translation should be correct.


    Wednesday, December 6, 2017 1:55 AM
  • Hello Ante,

    Is there any update or any other assistance I could provide ? You could mark the helpful reply as answer if the issue has been solved. And if you have any concerns, please do not hesitate to let us know.

    Thank you for your understanding and patience!

    Best regards,

    Neil Hu


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Sunday, December 24, 2017 7:39 AM
    Moderator