This commit is contained in:
sin365 2024-06-14 14:16:02 +08:00
commit eab66b0a04
4 changed files with 189 additions and 0 deletions

113
HunterIDHelper.cs Normal file
View File

@ -0,0 +1,113 @@
using System.Text;
namespace MHFCharacterIDConverter
{
public static class HunterIDHelper
{
public static string UIntIDToInGameID(uint Id)
{
string base32String = MHFBase32Converter.ToBase32((int)Id);
string inGameID = Base32StringToInGameID(base32String);
return inGameID;
}
public static uint InGameIDToUIntID(string inGameID)
{
string base32String = InGameIDToBase32String(inGameID);
uint Id = (uint)MHFBase32Converter.FromBase32(base32String);
return Id;
}
static string Base32StringToInGameID(string str)
{
string result = "";
for (int i = str.Length - 1; i >= 0; i--)
{
result += str[i];
}
while (result.Length < 6)
{
result += "1";
}
return result;
}
static string InGameIDToBase32String(string str)
{
string result = "";
for (int i = 0; i < str.Length; i++)
result = str[i] + result;
List<char> temp = result.ToList();
result = "";
bool bhadfristVal = false;
for (int i = 0; i < temp.Count; i++)
{
if (!bhadfristVal && temp[i] == '1')
continue;
bhadfristVal = true;
result += temp[i];
}
return result;
}
}
public static class MHFBase32Converter
{
private const string Base35Chars = "123456789ABCDEFGHJKLMNPQRTUVWXYZ"; // 35个字符从'1'到'Z'
// 整数转换为35进制字符串自定义的其中'1'代表0
public static string ToBase32(int number)
{
StringBuilder result = new StringBuilder();
while (number > 0)
{
int remainder = number % 32;
result.Insert(0, Base35Chars[remainder]); // 注意这里不需要减1因为直接从'1'开始
number /= 32;
}
// 如果number是0则添加'1'表示
if (result.Length == 0)
{
result.Append(Base35Chars[0]);
}
return result.ToString();
}
// 35进制字符串转换为整数自定义的其中'1'代表0
public static int FromBase32(string base32String)
{
if (string.IsNullOrWhiteSpace(base32String)) throw new ArgumentNullException(nameof(base32String));
int result = 0;
int power = 1;
for (int i = base32String.Length - 1; i >= 0; i--)
{
char currentChar = base32String[i];
int index = Base35Chars.IndexOf(currentChar);
if (index == -1)
{
throw new ArgumentException("Invalid character in base32 string.");
}
// 如果第一个字符是'1'则不需要加1因为'1'代表0
result += (i == 0 && currentChar == '1' ? 0 : index) * power;
power *= 32;
}
return result;
}
}
}

View File

@ -0,0 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<PublishAot>true</PublishAot>
<InvariantGlobalization>true</InvariantGlobalization>
</PropertyGroup>
</Project>

17
Program.cs Normal file
View File

@ -0,0 +1,17 @@
namespace MHFCharacterIDConverter
{
internal class Program
{
static void Main(string[] args)
{
//Test
for (uint i = 1; i < 1300u; i++)
{
string InGameID = HunterIDHelper.UIntIDToInGameID(i);
uint reConvID = HunterIDHelper.InGameIDToUIntID(InGameID);
Console.WriteLine($"srcCharID: {i} | InGameID: {InGameID} | reConvID: {reConvID}");
}
Console.ReadLine();
}
}
}

47
README.md Normal file
View File

@ -0,0 +1,47 @@
##[Cn]
在Monster Hunter Frontier (任意版本) 中浏览角色信息有一个ID形如"W6BX11",这种六位数。
通过查看服务端代码和截取包发现服务器仅发送了uint32的数据库的CharacterID并没有发送"W6BX11"这种字符串。
这完全是客户端逻辑为了不显示真实ID做了一个换算。
我搞清楚了其换算机制,机制如下:
1. MHF客户端是基于0~Z的36进制但是把0IOS 这四个字符扔了变成32进制。
2. 从0到32的数值对应的表示符号是“123456789ABCDEFGHJKLMNPQRTUVWXYZ”
3. 按照如上对应表把uint32的CharacterID进行转换之后。
4. 将结果倒序,(并不是HEX的高位在前是直接整个字符串倒序
5. 然后不足6位填充“1”因为“1”就是0
相反的行为,换算回去
已用于皓月云MHF-FW5在线网页游戏实况的需要内存采集的一部分功能。
##[En]
In Monster Hunter Frontier (any version), when browsing character information, there is an ID in the form of "W6BX11", a six-digit number.
By checking the server code and intercepting the package, it was found that the server only sent the CharacterID of the uint32 database, and did not send the string "W6BX11".
This is completely client logic. In order not to display the real ID, a conversion was made.
I figured out its conversion mechanism, which is as follows:
1. The MHF client is based on 36-decimal system 0~Z, but the four characters '0', 'I', 'O', and 'S' are thrown away and converted to 32-decimal system.
2. The corresponding symbols for the values from 0 to 32 are "123456789ABCDEFGHJKLMNPQRTUVWXYZ"
3. According to the corresponding table above, convert the CharacterID of uint32.
4. Reverse the result (not the high bit of HEX first, but the whole string in reverse order)
5. Then fill "1" if there are less than 6 bits, because "1" is 0
The opposite behavior, convert back
It has been used for some functions of axibug.com MHF-FW5 online web game live that require memory acquisition.