归档
This commit is contained in:
commit
eab66b0a04
113
HunterIDHelper.cs
Normal file
113
HunterIDHelper.cs
Normal 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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
12
MHFCharacterIDConverter.csproj
Normal file
12
MHFCharacterIDConverter.csproj
Normal 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
17
Program.cs
Normal 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
47
README.md
Normal file
@ -0,0 +1,47 @@
|
||||
##[Cn]
|
||||
|
||||
在Monster Hunter Frontier (任意版本) 中,浏览角色信息,有一个ID,形如"W6BX11",这种六位数。
|
||||
|
||||
通过查看服务端代码和截取包,发现服务器仅发送了uint32的数据库的CharacterID,并没有发送"W6BX11"这种字符串。
|
||||
|
||||
这完全是客户端逻辑,为了不显示真实ID,做了一个换算。
|
||||
|
||||
我搞清楚了其换算机制,机制如下:
|
||||
|
||||
1. MHF客户端是基于0~Z的36进制,但是把‘0’、‘I’、‘O’、‘S’ 这四个字符扔了,变成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.
|
Loading…
Reference in New Issue
Block a user