String.md5_text
2026/4/14大约 4 分钟
最后同步日期:2026-04-15 | Godot 官方原文 — String.md5_text
String.md5_text
定义
String.md5_text 就是把一段文字变成一个独一无二的"指纹"——一串固定长度的字符。不管你的原文是 1 个字还是 1 万个字,出来的指纹都是 32 个字符。而且只要原文哪怕改了一个标点,指纹就会完全不同。
打个比方:MD5 就像一个超级盖章机。你把文件放进去,它盖出一个独一无二的印章。同样的文件永远盖出同样的印章,不同的文件盖出不同的印章。但你不能从印章反推出文件长什么样(单向的)。
在实际游戏开发中,MD5 常用于:验证文件是否被修改过(校验下载完整性)、给数据生成唯一标识符、简单的密码哈希存储等。注意 MD5 已不推荐用于安全加密场景,但用于校验和标识仍然很方便。
函数签名
C#
// C# 中使用 System.Security.Cryptography
using System.Security.Cryptography;
using System.Text;
public static string Md5Text(string input)
{
byte[] hash = MD5.HashData(Encoding.UTF8.GetBytes(input));
return Convert.ToHexString(hash).ToLower();
}GDScript
func md5_text() -> String
# 也可以对 PackedByteArray 使用:
# var hash = data.md5_string()参数说明
| 参数 | 类型 | 必需 | 说明 |
|---|---|---|---|
| 无 | — | — | 此方法没有参数(作用于字符串自身) |
返回值
String —— 返回 32 个字符的十六进制字符串(小写)。例如 "d41d8cd98f00b204e9800998ecf8427e"。
代码示例
基础用法:计算字符串的 MD5 值
C#
using System.Security.Cryptography;
using System.Text;
string input = "Hello World";
string hash = Convert.ToHexString(MD5.HashData(Encoding.UTF8.GetBytes(input))).ToLower();
GD.Print(hash);
// 运行结果: "ed076287532e86365e841e92bfc50d8c"
string empty = Convert.ToHexString(MD5.HashData(Encoding.UTF8.GetBytes(""))).ToLower();
GD.Print(empty);
// 运行结果: "d41d8cd98f00b204e9800998ecf8427e"(空字符串的 MD5)GDScript
var input = "Hello World"
var hash = input.md5_text()
print(hash)
# 运行结果: "ed076287532e86365e841e92bfc50d8c"
var empty = "".md5_text()
print(empty)
# 运行结果: "d41d8cd98f00b204e9800998ecf8427e"(空字符串的 MD5)实际场景:校验配置文件是否被修改
C#
using Godot;
using System.Security.Cryptography;
using System.Text;
public partial class ConfigValidator : Node
{
private string _lastConfigHash = "";
public void SaveConfigWithHash(string configPath, string content)
{
// 保存配置内容
var file = FileAccess.Open(configPath, FileAccess.ModeFlags.Write);
file.StoreString(content);
file.Close();
// 计算并保存 MD5 校验值
string hash = Convert.ToHexString(MD5.HashData(Encoding.UTF8.GetBytes(content))).ToLower();
_lastConfigHash = hash;
var hashFile = FileAccess.Open(configPath + ".md5", FileAccess.ModeFlags.Write);
hashFile.StoreString(hash);
hashFile.Close();
// 运行结果: 保存配置文件及其 MD5 校验文件
}
public bool ValidateConfig(string configPath)
{
var file = FileAccess.Open(configPath, FileAccess.ModeFlags.Read);
string content = file.GetAsText();
file.Close();
var hashFile = FileAccess.Open(configPath + ".md5", FileAccess.ModeFlags.Read);
string savedHash = hashFile.GetAsText().StripEdges();
hashFile.Close();
string currentHash = Convert.ToHexString(MD5.HashData(Encoding.UTF8.GetBytes(content))).ToLower();
bool valid = currentHash == savedHash;
GD.Print($"配置校验:{(valid ? "通过" : "文件已被修改")}");
// 运行结果: 如果文件没被修改打印"通过",否则打印"文件已被修改"
return valid;
}
}GDScript
extends Node
var _last_config_hash: String = ""
func save_config_with_hash(config_path: String, content: String):
# 保存配置内容
var file = FileAccess.open(config_path, FileAccess.WRITE)
file.store_string(content)
file.close()
# 计算并保存 MD5 校验值
var hash = content.md5_text()
_last_config_hash = hash
var hash_file = FileAccess.open(config_path + ".md5", FileAccess.WRITE)
hash_file.store_string(hash)
hash_file.close()
# 运行结果: 保存配置文件及其 MD5 校验文件
func validate_config(config_path: String) -> bool:
var file = FileAccess.open(config_path, FileAccess.READ)
var content = file.get_as_text()
file.close()
var hash_file = FileAccess.open(config_path + ".md5", FileAccess.READ)
var saved_hash = hash_file.get_as_text().strip_edges()
hash_file.close()
var current_hash = content.md5_text()
var valid = current_hash == saved_hash
print("配置校验:%s" % ("通过" if valid else "文件已被修改"))
# 运行结果: 如果文件没被修改打印"通过",否则打印"文件已被修改"
return valid进阶用法:用 MD5 生成关卡唯一标识
C#
using Godot;
using System.Security.Cryptography;
using System.Text;
using System.Collections.Generic;
public partial class LevelManager : Node
{
private Dictionary<string, string> _levelHashes = new();
public string RegisterLevel(string levelName, string levelData)
{
string hash = Convert.ToHexString(MD5.HashData(Encoding.UTF8.GetBytes(levelName + levelData))).ToLower();
_levelHashes[levelName] = hash;
GD.Print($"关卡 '{levelName}' 注册成功,ID:{hash[..8]}...");
// 运行结果: 打印如 "关卡 '森林关卡' 注册成功,ID:a3f2b1c0..."
return hash;
}
public bool IsLevelModified(string levelName, string currentData)
{
if (!_levelHashes.ContainsKey(levelName)) return true;
string currentHash = Convert.ToHexString(MD5.HashData(Encoding.UTF8.GetBytes(levelName + currentData))).ToLower();
bool modified = currentHash != _levelHashes[levelName];
// 运行结果: 如果关卡数据有变化返回 true
return modified;
}
}GDScript
extends Node
var _level_hashes: Dictionary = {}
func register_level(level_name: String, level_data: String) -> String:
var hash = (level_name + level_data).md5_text()
_level_hashes[level_name] = hash
print("关卡 '%s' 注册成功,ID:%s..." % [level_name, hash.substr(0, 8)])
# 运行结果: 打印如 "关卡 '森林关卡' 注册成功,ID:a3f2b1c0..."
return hash
func is_level_modified(level_name: String, current_data: String) -> bool:
if not _level_hashes.has(level_name):
return true
var current_hash = (level_name + current_data).md5_text()
var modified = current_hash != _level_hashes[level_name]
# 运行结果: 如果关卡数据有变化返回 true
return modified注意事项
- MD5 不适合密码存储:MD5 被证明存在碰撞漏洞,不建议用于存储密码。密码存储应使用 SHA-256 或更强的哈希算法配合盐值(salt)。
- C# 中需要使用 .NET 标准库:C# 没有 Godot 内置的
Md5Text()方法,需要使用System.Security.Cryptography.MD5。 - 输出长度固定:无论输入多长,MD5 输出始终是 32 个十六进制字符(128 位)。
- 单向不可逆:你无法从 MD5 哈希值反推出原始内容。这既是优点(安全性)也是限制(无法恢复原文)。
- 与
md5_buffer的区别:GDScript 的md5_buffer()返回的是PackedByteArray(原始字节),而md5_text()返回的是十六进制字符串。
