#1
  1. Contributing User
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Dec 2004
    Location
    Meriden, Connecticut
    Posts
    1,797
    Rep Power
    154

    Translation Problem


    I'm having trouble translating the following code.Hash = Mid
    Code:
    Hash = Mid(Mid(Data, 34), InStr(Mid(Data, 34), Chr(0)) + 1, InStr(Mid(Mid(Data, 34), InStr(Data, Chr(0)) + 1), Chr(0)))
    To Python. Because of the way Visual Basic's Mid() function works, I have no clue what's going on in this code. I got as far as this:
    Code:
    hash = data[data[33:], data.find(data[33:]),
    I know that isn't very far at all. But I was becoming very confused, I wasn't sure where the first Mid() was doing around the second Mid(). I will appreciate any help.
  2. #2
  3. Hello World :)
    Devshed Frequenter (2500 - 2999 posts)

    Join Date
    Mar 2003
    Location
    Hull, UK
    Posts
    2,537
    Rep Power
    69
    I don't and probably never will know VB but you might want to stop trying to translate code and learn Python . I think you'll find things much easier if you do.

    Anyway, what does the line do (or what is it surposed to do). If you give us some sample text and the value you want I'm sure we can work something out .

    Take care,

    Mark.
    programming language development: www.netytan.com Hula

  4. #3
  5. Commie Mutant Traitor
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Jun 2004
    Location
    Norcross, GA (again)
    Posts
    1,804
    Rep Power
    1569
    I've said the same before, Mark, but to no avail. While your persistence is admirable, Yegg, I would think that you would eventually get tired of beating yourself agains this particular wall. As I've said a number of times, VB and Python are too different for a direct transliteration to be practical.

    As for this particular problem, well, let me start by saying that the code-monkey who wrote that VB fragment should be shot. Unfortunately, it is all too typical of VB code, and of the particular program you are trying to duplicate. The fact that he makes the same function call three times in a single line is enough to make me weep. Do us all a favor and send the VB source code to The Daily WTF for proper excoriation, then bury your own copy at the crossroads at midnight with a stake through it's disk spindle.

    If you insist on it, then I'd advise you to break up the expression into a number of sub-expressions, over perhaps a half dozen lines. Let's start by indenting this Lisp-fashion to show the individual function calls:

    Code:
    Hash = Mid(Mid(Data, 34),  _ ' initial substring
     
               ' final substring start point
               InStr(Mid(Data, 34), Chr(0)) + 1,  _
      
               ' final substring endpoint
               InStr(Mid(Mid(Data, 34),  _
                         InStr(Data, Chr(0)) + 1),  _
                     Chr(0)))
    This shows a bit clearer what it's doing - it is taking the substring of Data beginning at character 34, then taking a substring of that that begins one char past the first null that appears in the first substring, and ending at (bear with me here) a position determined from the position of the first null following an offset into that first substring matching the location one char past the first null in the original string (I feel woozy).

    Either the protocol designer was insane, or (more likely) the VB coder had no clue what he was doing. Let's break the VB code into separate lines nd see if it's any clearer.
    Code:
    null_char = chr(0)
    data_tail = mid(Data, 34) ' the substring to parse
    
    ' the starting point of the final substring
    hash_start = InStr(data_tail, null_char) + 1
    
    ' the end point of the final substring
    data_null_offset = InStr(Data, null_char) + 1
    offset_substr = Mid(data_tail,  data_null_offset)
    hash_end = InStr(offset_substr, null_char)
    
    ' extract the final substring containing the hash (MD5 sig?)
    hash = Mid(data_tail, hash_start, hash_end)
    Converting this to Python:

    Code:
    null_char = '\0'
    data_tail = Data[33:]  # the substring to parse
    
    # the starting point of the final substring
    # doesn't need the '+ 1' offset because of 
    # how the slice operator works
    hash_start = data_tail.find(null_char)
    
    # the end point of the final substring
    data_null_offset = Data.find(null_char)
    offset_substr = data_tail[data_null_offset:]
    hash_end = offset_substr.find(null_char)
    
    # extract the final substring containing the hash (MD5 sig?)
    hash = data_tail[hash_start:hash_end]
    This is still execrable code, but it should come within earshot of working. I wish I knew more about just what it is trying to implement; I'm certain there has to be an easier way to do this, but I'm too tired right now to work it out.

    Comments and Corrections Welcome.

    Comments on this post

    • SimonGreenhill agrees
    Last edited by Schol-R-LEA; March 26th, 2005 at 07:36 PM.
    Rev First Speaker Schol-R-LEA;2 JAM LCF ELF KoR KCO BiWM TGIF
    #define KINSEY (rand() % 7) λ Scheme is the Red Pill
    Scheme in Short Understanding the C/C++ Preprocessor
    Taming Python A Highly Opinionated Review of Programming Languages for the Novice, v1.1

    FOR SALE: One ShapeSystem 2300 CMD, extensively modified for human use. Includes s/w for anthro, transgender, sex-appeal enhance, & Gillian Anderson and Jason D. Poit clone forms. Some wear. $4500 obo. tverres@et.ins.gov
  6. #4
  7. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2005
    Posts
    78
    Rep Power
    10
    Originally Posted by Schol-R-LEA
    This is still excrable code, but it should come within earshot of working. I wish I knew more about just what it is trying to implement; I'm certain there has to be an easier way to do this, but I'm too tired right now to work it out.

    Comments and Corrections Welcome.
    Yup ... it's ghastly. The bright side is there IS a better way of doing it:
    Code:
    hash = Data[33:].split('\0')[1]
    Understanding why it should work is left as an exercise for Yegg ;-)

    --OH.
    ps: "data" is a better name for a variable than "Data" since "Data" implies a class.
  8. #5
  9. Contributing User
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Dec 2004
    Location
    Meriden, Connecticut
    Posts
    1,797
    Rep Power
    154
    Netytan, it's not so much learnign Python. Back in the day when Battle.net bot's first were being created, the early programmers obviously didn't know near as much then as they know now. That code is over 5 years old, that's probably why it's so horrible. This code which most people use or create a copy like it for their bots, is needed for having a hashed connection (using the game clients hash files) to a Battle.net game. This one works only for Starcraft. I'm pretty sure most of the code I can figure out how to translate, but it was just this line that seemed very confusing. There was two Mid() functions one over the other, and there were too many comma's to concentrate on, I kept forgetting where one Mid() began and the other ended. Thanks for all the help Schol-R-LEA.
  10. #6
  11. Commie Mutant Traitor
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Jun 2004
    Location
    Norcross, GA (again)
    Posts
    1,804
    Rep Power
    1569
    A pair of footnotes:

    After I posted this, I remembered that VB 6 and earlier already had a named constant for the null character, not surprisingly named vbNullChar. I wonder if the person who wrote the original even knew it.

    Netytan's solution (assuming it is correct, which it certainly appears to be) implies that the protocol in question (or at least this part of it) consists of a fixed 34-byte header followed by a series null-delimited fields, the second of which contains the hash code in question. If so, then the obvious VB solution would have been something like

    Code:
    DataTail = Mid(data, 34)
    DataFields = split(DataTail, vbNullChar)
    hash = DataFields(1)
    Why didn't the original coder do that? Certainly not because it was easier; the original line shows a twisted sort of ingenuity, and must have taken hours to devise. Perhaps the coder didn't know about the split() function, but you'd think that if you were have so much trouble with a piece of code that the original line was the best you could come up with, you would crack open a reference book to try and find a better solution. Who knows?

    Anyway, as a correctness test for this, perhaps Yegg can take this code (with the appropriate declarations) and insert it into the VB code as a replacement for the original. This should tell us conclusively if it works right or not.
    Last edited by Schol-R-LEA; March 26th, 2005 at 07:32 PM.
    Rev First Speaker Schol-R-LEA;2 JAM LCF ELF KoR KCO BiWM TGIF
    #define KINSEY (rand() % 7) λ Scheme is the Red Pill
    Scheme in Short Understanding the C/C++ Preprocessor
    Taming Python A Highly Opinionated Review of Programming Languages for the Novice, v1.1

    FOR SALE: One ShapeSystem 2300 CMD, extensively modified for human use. Includes s/w for anthro, transgender, sex-appeal enhance, & Gillian Anderson and Jason D. Poit clone forms. Some wear. $4500 obo. tverres@et.ins.gov
  12. #7
  13. Contributing User
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Dec 2004
    Location
    Meriden, Connecticut
    Posts
    1,797
    Rep Power
    154
    Hmm, I'm sure the original coder knew about the split() function. After all, this was one of the earliest forms of starcraft hashing. They must have known enough about what they were doing. When I get some time, I will try that code and see if it works correctly.

IMN logo majestic logo threadwatch logo seochat tools logo