Jump to content
    1. Welcome to GTAForums!

    1. GTANet.com

    1. GTA Online

      1. The Criminal Enterprises
      2. Updates
      3. Find Lobbies & Players
      4. Guides & Strategies
      5. Vehicles
      6. Content Creator
      7. Help & Support
    2. Red Dead Online

      1. Blood Money
      2. Frontier Pursuits
      3. Find Lobbies & Outlaws
      4. Help & Support
    3. Crews

    1. Grand Theft Auto Series

      1. Bugs*
      2. St. Andrews Cathedral
    2. GTA VI

    3. GTA V

      1. Guides & Strategies
      2. Help & Support
    4. GTA IV

      1. The Lost and Damned
      2. The Ballad of Gay Tony
      3. Guides & Strategies
      4. Help & Support
    5. GTA San Andreas

      1. Classic GTA SA
      2. Guides & Strategies
      3. Help & Support
    6. GTA Vice City

      1. Classic GTA VC
      2. Guides & Strategies
      3. Help & Support
    7. GTA III

      1. Classic GTA III
      2. Guides & Strategies
      3. Help & Support
    8. Portable Games

      1. GTA Chinatown Wars
      2. GTA Vice City Stories
      3. GTA Liberty City Stories
    9. Top-Down Games

      1. GTA Advance
      2. GTA 2
      3. GTA
    1. Red Dead Redemption 2

      1. PC
      2. Help & Support
    2. Red Dead Redemption

    1. GTA Mods

      1. GTA V
      2. GTA IV
      3. GTA III, VC & SA
      4. Tutorials
    2. Red Dead Mods

      1. Documentation
    3. Mod Showroom

      1. Scripts & Plugins
      2. Maps
      3. Total Conversions
      4. Vehicles
      5. Textures
      6. Characters
      7. Tools
      8. Other
      9. Workshop
    4. Featured Mods

      1. Design Your Own Mission
      2. OpenIV
      3. GTA: Underground
      4. GTA: Liberty City
      5. GTA: State of Liberty
    1. Rockstar Games

    2. Rockstar Collectors

    1. Off-Topic

      1. General Chat
      2. Gaming
      3. Technology
      4. Movies & TV
      5. Music
      6. Sports
      7. Vehicles
    2. Expression

      1. Graphics / Visual Arts
      2. GFX Requests & Tutorials
      3. Writers' Discussion
      4. Debates & Discussion
    1. Announcements

    2. Support

    3. Suggestions

*DO NOT* SHARE MEDIA OR LINKS TO LEAKED COPYRIGHTED MATERIAL. Discussion is allowed.

[C#] String Hasher


Fireboyd78
 Share

Recommended Posts

I have made a simple hash key generator that is guaranteed to generate a hash in the same manner as the game itself. This isn't really needed for people who are writing simple scripts, but for those of you who are working on reverse engineering the pesky file formats in this game (such as myself), this is exactly what you've been looking for!

 

You may have heard of the Jenkins One-At-A-Time (JOAAT) hashing algorithm. This is indeed what is used; however, the game actually uses a lookup table for each individual character. For the longest time I wasn't aware of this, and was causing me horrible grief when trying to figure out why my hashes didn't match anything in the file. Sure enough, it turns out some characters get replaced ('\' with '/', for example) and all letters become lowercase. The particular hasher I was using only made letters lowercase, which was only partially correct. This has been resolved. I also added support for hashes with a concatenated value, where an additional string hash is added to the value (this is very rarely used, but may still useful).

 

Finally, here is the C# code along with XML documentation. I'm not too familiar with the RAGE family of games, so I wasn't sure if "RAGEHasher" would be an appropriate name or not. If it is, let me know and I'll rename it.

 

 

/// <summary>/// Represents a class for generating hash keys compatible with GTA 5 file formats./// </summary>public static class GTA5Hasher{    // copied directly from the game -- performs uppercase to lowercase conversions amongst other things    private static readonly byte[] m_LookupTable = {        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,        0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,        0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,        0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,        0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x5B, 0x2F, 0x5D, 0x5E, 0x5F,        0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,        0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,        0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,        0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,        0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,        0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,        0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,        0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,        0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,        0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF,    };    private static uint GetHashKeySubString(string str, uint initialHash)    {        var hash = initialHash;        for (int i = 0; i < str.Length; i++)        {            hash += m_LookupTable[str[i]];            hash += (hash << 10);            hash ^= (hash >> 6);        }        return hash;    }    private static uint GetHashKeyFinalize(string str, uint initialHash)    {        var hash = GetHashKeySubString(str, initialHash);        hash += (hash << 3);        hash ^= (hash >> 11);        hash += (hash << 15);        return hash;    }    /// <summary>    /// Gets the hash key of the specified string.    /// </summary>    /// <param name="str">The string used to generate a hash key.</param>    /// <returns>A hash key compatible with GTA 5.</returns>    public static uint GetHashKey(string str)    {        return GetHashKey(str, 0);    }    /// <summary>    /// Gets the hash key of the specified string, using an initial hash key value.    /// </summary>    /// <param name="str">The string used to generate a hash key.</param>    /// <param name="initialHash">The initial hash key value used to generate the result.</param>    /// <returns>A hash key compatible with GTA 5.</returns>    public static uint GetHashKey(string str, uint initialHash)    {        return GetHashKeyFinalize(str, initialHash);    }    /// <summary>    /// Gets the hash key of the specified string concatenated with an additional string.    /// </summary>    /// <param name="str">The string used to generate a hash key.</param>    /// <param name="concat">The additional string to concatenate to the input string.</param>    /// <returns>A hash key compatible with GTA 5.</returns>    public static uint GetHashKey(string str, string concat)    {        return GetHashKey(str, concat, 0);    }    /// <summary>    /// Gets the hash key of the specified string concatenated with an additional string, using an initial hash key value.    /// </summary>    /// <param name="str">The string used to generate a hash key.</param>    /// <param name="concat">The additional string to concatenate to the input string.</param>    /// /// <param name="initialHash">The initial hash key value used to generate the result.</param>    /// <returns>A hash key compatible with GTA 5.</returns>    public static uint GetHashKey(string str, string concat, uint initialHash)    {        return GetHashKeyFinalize(concat, GetHashKeySubString(str, initialHash));    }}
No credit needed, but is always appreciated! Edited by Fireboyd78
  • Like 3
Link to comment
Share on other sites

I think this should be in Documentation. :)

Great post btw!

Thank you. I figured Documentation was more for file formats, and Coding was for well...code :p

Link to comment
Share on other sites

Thank you. I figured Documentation was more for file formats, and Coding was for well...code :p

Ah yeah I agree now. Just read the description of the Coding forum and it says it's for code snippets and such. I generally think of this forum is for coding questions and not coding snippets, as that's what it's generally used for.

Link to comment
Share on other sites

  • 4 years later...

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • 1 User Currently Viewing
    0 members, 0 Anonymous, 1 Guest

×
×
  • Create New...

Important Information

By using GTAForums.com, you agree to our Terms of Use and Privacy Policy.