资讯动态

新手必看:用__DATE__和__TIME__宏为你的C程序添加‘出生证明‘

发布时间:2026/8/10 20:51:42 来源:尧图企业网站定制
为你的C程序制作出生证明__DATE__和__TIME__宏实战指南当你运行一个程序时有没有想过它是什么时候出生的就像人类有出生证明一样C程序也可以通过预处理器宏记录自己的编译时间戳。这不仅是一个有趣的彩蛋更是调试和版本管理的重要工具。今天我们就来探索如何用__DATE__和__TIME__这两个神奇的宏为你的代码添加时间记忆功能。1. 认识程序的身份证预处理器宏基础在C语言的世界里预处理器就像是代码的化妆师在正式编译前对源代码进行各种修饰。而__DATE__和__TIME__就是它提供的两个特殊工具能够自动记录代码被编译的精确时刻。1.1 什么是__DATE__和__TIME__这两个宏是C标准定义的内建宏不需要任何头文件就能直接使用__DATE__以MMM DD YYYY格式表示编译日期如Jun 01 2023__TIME__以HH:MM:SS格式表示编译时间如14:25:30它们的神奇之处在于编译器会自动用当前的日期和时间替换这些宏就像魔法一样#include stdio.h int main() { printf(本程序诞生于%s %s\n, __DATE__, __TIME__); return 0; }运行这段代码你会看到类似这样的输出本程序诞生于Jun 01 2023 14:25:301.2 为什么需要记录编译时间你可能好奇为什么要费心记录这些信息以下是几个实际应用场景版本追踪当用户报告bug时你可以快速确认他们使用的程序版本构建验证确保测试环境运行的是最新编译的程序日志分析在日志中标记程序构建时间便于问题排查自动化部署与CI/CD系统集成验证部署的正确性2. 实战演练构建你的第一个出生证明现在让我们动手创建一个完整的示例展示如何优雅地使用这些宏。2.1 基础版本简单输出#include stdio.h void print_build_info() { printf(╔════════════════════════════╗\n); printf(║ 程序出生证明 ║\n); printf(╠════════════════════════════╣\n); printf(║ 编译日期: %-15s ║\n, __DATE__); printf(║ 编译时间: %-15s ║\n, __TIME__); printf(╚════════════════════════════╝\n); } int main() { print_build_info(); return 0; }这个版本会输出一个美观的方框包含程序的编译日期和时间。注意%-15s中的-15是为了对齐文本使输出更整齐。2.2 进阶版本结合版本号在实际项目中我们通常会将编译时间与版本信息结合#include stdio.h #define VERSION_MAJOR 1 #define VERSION_MINOR 0 #define VERSION_PATCH 3 const char* get_build_info() { static char info[100]; snprintf(info, sizeof(info), v%d.%d.%d (built on %s at %s), VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH, __DATE__, __TIME__); return info; } int main() { printf(当前版本: %s\n, get_build_info()); return 0; }这个示例展示了如何创建一个返回完整版本信息的函数方便在整个程序中重复使用。3. 常见陷阱与解决方案即使是简单的宏使用也会遇到各种坑下面是一些常见问题及解决方法。3.1 格式不一致问题__DATE__和__TIME__的格式在不同编译器下基本一致但要注意月份缩写是英文的Jan、Feb等不适合直接用于中文环境日期和月份之间可能有空格如Jun 1而非Jun 01解决方案是编写一个格式化函数#include string.h void format_build_date(char* output) { char month[4]; int day, year; sscanf(__DATE__, %s %d %d, month, day, year); const char* months[] {Jan,Feb,Mar,Apr,May,Jun, Jul,Aug,Sep,Oct,Nov,Dec}; int month_num 0; for(; month_num12; month_num) { if(strcmp(month, months[month_num]) 0) break; } sprintf(output, %04d年%02d月%02d日, year, month_num1, day); }3.2 时区问题__TIME__反映的是编译时的系统时间如果构建服务器位于不同时区可能导致时间显示不一致。解决方法在构建脚本中设置统一的时区使用UTC时间并明确标注printf(编译时间(UTC): %s\n, __TIME__);3.3 调试版本与发布版本的区别有时你可能希望只在调试版本中包含编译时间信息#ifdef DEBUG printf(调试版本构建于: %s %s\n, __DATE__, __TIME__); #endif这样在发布版本中就不会显示这些信息了。4. 创意应用超越基础用法掌握了基本用法后让我们看看如何将这些宏玩出花样。4.1 创建唯一的构建ID结合日期时间和随机数可以生成唯一的构建标识符#include stdlib.h #include time.h unsigned int generate_build_id() { unsigned int seed 0; sscanf(__TIME__, %2hhd%2hhd%2hhd, seed, seed1, seed2); srand(seed); return rand(); } int main() { printf(构建ID: %u\n, generate_build_id()); return 0; }4.2 实现程序年龄计算让程序知道自己已经活了多久#include time.h void print_program_age() { struct tm build_time {0}; sscanf(__DATE__ __TIME__, %s %d %d %d:%d:%d, build_time.tm_mon, build_time.tm_mday, build_time.tm_year, build_time.tm_hour, build_time.tm_min, build_time.tm_sec); // 转换月份缩写为数字 const char* months[] {Jan,Feb,Mar,Apr,May,Jun, Jul,Aug,Sep,Oct,Nov,Dec}; for(build_time.tm_mon0; build_time.tm_mon12; build_time.tm_mon) { if(strcmp(build_time.tm_mon, months[build_time.tm_mon]) 0) break; } build_time.tm_year - 1900; time_t build_timestamp mktime(build_time); time_t now time(NULL); double seconds difftime(now, build_timestamp); printf(本程序已经运行了 %.1f 天\n, seconds / 86400); }4.3 自动生成版权声明在程序启动时显示动态版权信息void show_copyright() { int year; sscanf(__DATE__, %*s %*d %d, year); printf(© %d 你的公司名称. 保留所有权利。\n, year); }5. 高级技巧与构建系统集成真正的项目通常使用构建系统如Make或CMake我们可以更好地集成这些宏。5.1 Makefile中的时间戳在Makefile中定义更详细的版本信息BUILD_DATE : $(shell date %Y-%m-%d) BUILD_TIME : $(shell date %H:%M:%S) CFLAGS -DBUILD_DATE\$(BUILD_DATE)\ -DBUILD_TIME\$(BUILD_TIME)\然后在代码中printf(构建于: %s %s\n, BUILD_DATE, BUILD_TIME);5.2 使用CMake的configure_fileCMake可以生成包含构建信息的头文件configure_file( ${PROJECT_SOURCE_DIR}/version.h.in ${PROJECT_BINARY_DIR}/version.h )version.h.in内容#define BUILD_DATE BUILD_DATE #define BUILD_TIME BUILD_TIME #define GIT_HASH GIT_COMMIT_HASH5.3 自动化版本递增结合Git提交信息自动生成版本号#!/bin/bash # get_version.sh COMMIT_COUNT$(git rev-list --count HEAD) DATE$(date %Y%m%d) echo #define VERSION \1.0.$COMMIT_COUNT-$DATE\ version.h然后在Makefile中version.h: .git/HEAD .git/index ./get_version.sh6. 跨平台注意事项不同平台和编译器可能有些细微差别需要注意6.1 Windows下的特殊处理某些Windows编译器可能需要#pragma message(编译时间: __DATE__ __TIME__)6.2 嵌入式系统的限制在资源受限的环境中可能需要优化字符串存储const char build_date[] __DATE__; const char build_time[] __TIME__;6.3 处理非英语区域设置如果你的系统区域设置不是英语月份缩写可能不同。最安全的方法是const char* months_en[] {Jan,Feb,Mar,Apr,May,Jun, Jul,Aug,Sep,Oct,Nov,Dec}; setlocale(LC_TIME, C);7. 安全考虑与最佳实践虽然这些宏很有用但也需要注意一些安全问题。7.1 不要暴露敏感信息避免在公开发布的程序中包含精确的构建时间这可能被攻击者利用// 不好的做法 printf(构建于: %s %s by %s\n, __DATE__, __TIME__, admin); // 更好的做法 printf(版本: %d.%d.%d\n, MAJOR, MINOR, PATCH);7.2 日志中的时间戳在日志中使用运行时时间而非编译时间#include time.h void log_message(const char* msg) { time_t now; time(now); printf([%s] %s\n, ctime(now), msg); }7.3 版本信息的存储位置考虑将版本信息集中管理// version.h #ifndef VERSION_H #define VERSION_H #define VERSION 1.0.0 extern const char* get_build_info(void); #endif// version.c #include version.h #include stdio.h const char* get_build_info(void) { static char buffer[50]; snprintf(buffer, sizeof(buffer), %s (built on %s), VERSION, __DATE__); return buffer; }8. 实际项目中的应用案例让我们看几个真实场景中如何使用这些技术。8.1 命令行工具的版本信息// 处理--version参数 if(argc 2 strcmp(argv[1], --version) 0) { printf(%s %s\n, my_tool, get_build_info()); return 0; }8.2 图形界面程序中的关于对话框void show_about_dialog(GtkWidget* parent) { GtkWidget* dialog gtk_about_dialog_new(); gtk_about_dialog_set_version(GTK_ABOUT_DIALOG(dialog), get_build_info()); // 其他设置... gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(dialog); }8.3 网络服务的HTTP头信息void handle_http_request(int sockfd) { char response[1024]; snprintf(response, sizeof(response), HTTP/1.1 200 OK\r\n Server: MyServer/%s\r\n X-Build-Date: %s\r\n \r\n, VERSION, __DATE__); write(sockfd, response, strlen(response)); }9. 性能考量与优化虽然这些宏很方便但在性能敏感的场景需要考虑其影响。9.1 字符串常量的存储每次使用__DATE__或__TIME__都会生成一个新的字符串常量。优化方法// 不好的做法多个重复字符串 printf(Date: %s\nTime: %s\n, __DATE__, __TIME__); // 好的做法只存储一次 static const char* build_date __DATE__; static const char* build_time __TIME__; printf(Date: %s\nTime: %s\n, build_date, build_time);9.2 避免频繁调用在循环中避免重复调用// 不好的做法 for(int i0; i1000; i) { log_message(__DATE__); } // 好的做法 const char* date __DATE__; for(int i0; i1000; i) { log_message(date); }9.3 预计算格式化的字符串// 初始化时 char version_string[100]; snprintf(version_string, sizeof(version_string), Version: %s, get_build_info()); // 之后可以重复使用version_string而不需要每次都格式化10. 替代方案与扩展思路除了标准宏还有其他记录构建信息的方法。10.1 使用__TIMESTAMP__某些编译器提供__TIMESTAMP__宏格式更详细printf(完整时间戳: %s\n, __TIMESTAMP__);10.2 获取文件修改时间通过文件系统获取源文件的最后修改时间#include sys/stat.h void print_file_time(const char* filename) { struct stat st; stat(filename, st); printf(最后修改: %s, ctime(st.st_mtime)); }10.3 集成Git提交信息在构建时注入Git信息# 在构建脚本中 GIT_HASH$(git rev-parse --short HEAD) echo #define GIT_COMMIT \$GIT_HASH\ git_info.h然后在代码中#include git_info.h printf(Git提交: %s\n, GIT_COMMIT);11. 调试技巧验证宏展开有时候需要确认宏是否正确展开可以使用这些技巧。11.1 使用gcc -E选项查看预处理后的代码gcc -E your_program.c11.2 静态断言验证确保宏确实被定义了#include assert.h static_assert(sizeof(__DATE__) 1, __DATE__ not defined);11.3 编译时打印某些编译器支持#pragma message (编译日期: __DATE__)12. 语言扩展C中的constexpr如果你使用C可以利用更现代的特性constexpr const char* get_build_date() { return __DATE__; } constexpr std::string_view build_date __DATE__;13. 自动化文档生成将构建信息集成到文档中/** * file main.c * version 1.0.0 * date 2023-06-01 * build 14:25:30 */然后使用Doxygen等工具自动生成文档。14. 单元测试中的运用在测试代码中验证版本信息#include string.h #include assert.h void test_build_info() { const char* info get_build_info(); assert(strstr(info, 2023) ! NULL); // 简单检查年份 }15. 多模块项目中的协调在大型项目中可能需要统一所有模块的构建信息。15.1 集中定义版本创建一个version.h被所有模块包含// version.h #ifndef VERSION_H #define VERSION_H #define PROJECT_VERSION 1.0.0 extern const char* get_global_build_info(void); #endif15.2 构建时生成头文件使用脚本生成统一的版本信息#!/bin/bash DATE$(date %F) TIME$(date %T) cat global_version.h EOF #ifndef GLOBAL_VERSION_H #define GLOBAL_VERSION_H #define BUILD_DATE $DATE #define BUILD_TIME $TIME #endif EOF16. 国际化考虑如果你的程序需要支持多语言日期格式可能需要转换。16.1 本地化日期显示#include locale.h #include time.h void print_localized_date() { struct tm tm; strptime(__DATE__, %b %d %Y, tm); setlocale(LC_TIME, ); char buffer[100]; strftime(buffer, sizeof(buffer), %x, tm); printf(本地日期: %s\n, buffer); }16.2 多语言月份名称手动转换英文月份const char* get_chinese_month(const char* en_month) { const char* months[12] {一月,二月,三月,四月,五月,六月, 七月,八月,九月,十月,十一月,十二月}; const char* en_months[12] {Jan,Feb,Mar,Apr,May,Jun, Jul,Aug,Sep,Oct,Nov,Dec}; for(int i0; i12; i) { if(strcmp(en_month, en_months[i]) 0) { return months[i]; } } return 未知; }17. 嵌入式系统特殊处理在资源受限的环境中可能需要特殊优化。17.1 使用PROGMEM (AVR)#include avr/pgmspace.h const char build_date[] PROGMEM __DATE__; const char build_time[] PROGMEM __TIME__;17.2 压缩日期格式将日期转换为更紧凑的格式uint32_t pack_build_date() { char month[4]; int day, year; sscanf(__DATE__, %s %d %d, month, day, year); // 将月份转换为1-12 int month_num ...; // 同前 return (year 16) | (month_num 8) | day; }18. 与调试信息的结合利用这些宏增强调试能力。18.1 断言消息#define MY_ASSERT(expr) \ do { \ if(!(expr)) { \ fprintf(stderr, 断言失败 %s %s (%s:%d)\n, \ __DATE__, __TIME__, __FILE__, __LINE__); \ abort(); \ } \ } while(0)18.2 崩溃报告void signal_handler(int sig) { fprintf(stderr, 程序崩溃! 版本: %s\n, get_build_info()); // 其他处理... }19. 可视化展示技巧让构建信息在图形界面中更吸引人。19.1 ASCII艺术void print_ascii_art() { printf( ____ _\n); printf( | _ \\ ___ _ __ | |_ ___ _ __ \n); printf( | |_) / _ \\| _ \\| __/ _ \\ __|\n); printf( | __/ (_) | | | | || __/ | \n); printf( |_| \\___/|_| |_|\\__\\___|_| \n); printf(\n构建于: %s %s\n, __DATE__, __TIME__); }19.2 进度条动画void show_build_info_animated() { const char* info get_build_info(); for(int i0; info[i]; i) { putchar(info[i]); fflush(stdout); usleep(100000); // 0.1秒延迟 } putchar(\n); }20. 构建系统的进阶集成最后我们看看如何与现代化构建工具深度整合。20.1 使用CMake的configure_timeCMake可以在配置时生成版本信息string(TIMESTAMP CONFIGURE_DATE %Y-%m-%d) string(TIMESTAMP CONFIGURE_TIME %H:%M:%S) configure_file(version.h.in version.h ONLY)20.2 自动递增构建号每次构建自动增加构建计数器# 读取当前构建号 file(READ build_number.txt BUILD_NUMBER) math(EXPR BUILD_NUMBER ${BUILD_NUMBER} 1) file(WRITE build_number.txt ${BUILD_NUMBER}) # 传递给编译器 add_definitions(-DBUILD_NUMBER${BUILD_NUMBER})20.3 结合CI系统在CI环境中注入更多信息if(DEFINED ENV{CI}) add_definitions(-DCI_BUILD1) add_definitions(-DCI_PIPELINE_ID$ENV{CI_PIPELINE_ID}) endif()21. 安全加固版本信息在某些安全敏感场景可能需要更严格的版本控制。21.1 哈希验证#include openssl/sha.h void print_secure_build_info() { unsigned char hash[SHA256_DIGEST_LENGTH]; SHA256((unsigned char*)__DATE__, strlen(__DATE__), hash); printf(安全构建标识: ); for(int i0; iSHA256_DIGEST_LENGTH; i) { printf(%02x, hash[i]); } printf(\n); }21.2 数字签名使用公钥加密构建信息// 伪代码 void sign_build_info() { EVP_PKEY* key load_private_key(key.pem); EVP_MD_CTX* ctx EVP_MD_CTX_new(); EVP_DigestSignInit(ctx, NULL, EVP_sha256(), NULL, key); EVP_DigestSignUpdate(ctx, __DATE__, strlen(__DATE__)); EVP_DigestSignUpdate(ctx, __TIME__, strlen(__TIME__)); size_t sig_len; EVP_DigestSignFinal(ctx, NULL, sig_len); unsigned char* sig malloc(sig_len); EVP_DigestSignFinal(ctx, sig, sig_len); // 存储或输出签名 save_signature(sig, sig_len); EVP_MD_CTX_free(ctx); free(sig); }22. 跨语言调用如果你的项目使用多种语言可能需要共享构建信息。22.1 生成C头文件供其他语言使用#!/bin/bash echo // autogenerated by build script build_info.h echo #define BUILD_DATE \$(date %F)\ build_info.h echo #define BUILD_TIME \$(date %T)\ build_info.h然后在Python中通过ctypes读取from ctypes import CDLL, c_char_p lib CDLL(./your_library.so) lib.get_build_info.restype c_char_p print(lib.get_build_info().decode())22.2 生成JSON配置文件void generate_build_json() { FILE* f fopen(build_info.json, w); fprintf(f, {\n); fprintf(f, \date\: \%s\,\n, __DATE__); fprintf(f, \time\: \%s\\n, __TIME__); fprintf(f, }\n); fclose(f); }23. 性能监控集成将构建信息与性能分析结合。23.1 性能基准标记void run_benchmark() { printf(性能测试 (版本: %s)\n, get_build_info()); clock_t start clock(); // 测试代码... clock_t end clock(); printf(耗时: %.2f秒\n, (double)(end - start)/CLOCKS_PER_SEC); }23.2 与profiler集成void profile_function() { printf(Profiling build: %s\n, __DATE__); // 开始性能分析 __itt_resume(); // 被分析的代码... __itt_pause(); }24. 容器化环境中的处理在Docker等容器环境中构建时间可能有特殊含义。24.1 容器构建时间ARG BUILD_DATE RUN echo BUILD_DATE$BUILD_DATE /etc/environment然后在代码中const char* get_container_build_date() { const char* date getenv(BUILD_DATE); return date ? date : unknown; }24.2 Kubernetes注解将构建信息作为Kubernetes注解apiVersion: apps/v1 kind: Deployment metadata: annotations: build-date: {{ .Values.buildDate }} build-time: {{ .Values.buildTime }}25. 终极技巧创建自描述程序结合所有技术创建一个能完整描述自己的程序。25.1 程序信息结构体struct program_info { const char* name; const char* version; const char* build_date; const char* build_time; const char* git_hash; const char* compiler; }; void init_program_info(struct program_info* info) { info-name My Awesome Program; info-version 1.0.0; info-build_date __DATE__; info-build_time __TIME__; info-git_hash GIT_HASH; info-compiler __VERSION__; }25.2 自检模式添加--self-check参数让程序验证自身if(argc 1 strcmp(argv[1], --self-check) 0) { struct program_info info; init_program_info(info); printf( 程序自检 \n); printf(名称: %s\n, info.name); printf(版本: %s\n, info.version); printf(构建时间: %s %s\n, info.build_date, info.build_time); printf(Git提交: %s\n, info.git_hash); printf(编译器: %s\n, info.compiler); return perform_self_checks() ? 0 : 1; }26. 自动化测试验证确保构建信息在测试中被正确验证。26.1 构建日期合理性检查void test_build_date() { int year; sscanf(__DATE__, %*s %*d %d, year); assert(year 2020 year 2100); }26.2 时间格式验证void test_time_format() { int hour, min, sec; int count sscanf(__TIME__, %d:%d:%d, hour, min, sec); assert(count 3); assert(hour 0 hour 24); assert(min 0 min 60); assert(sec 0 sec 60); }27. 文档生成自动化将构建信息自动集成到文档中。27.1 Doxygen集成/** * file main.c * version 1.0.0 * date Built on: __DATE__ __TIME__ */27.2 Markdown文档生成void generate_readme() { FILE* f fopen(README.md, w); fprintf(f, # 我的项目\n\n); fprintf(f, **版本**: %s\n\n, get_build_info()); fprintf(f, 最后构建于: %s %s\n, __DATE__, __TIME__); fclose(f); }28. 跨平台构建系统处理不同平台下的构建信息差异。28.1 Windows资源文件在.rc文件中#define BUILD_DATE_STR Built on: __DATE__ __TIME__ VS_VERSION_INFO VERSIONINFO FILEVERSION 1,0,0,0 PRODUCTVERSION 1,0,0,0 FILEFLAGSMASK 0x3fL FILEFLAGS 0x0L FILEOS VOS__WINDOWS32 FILETYPE VFT_APP FILESUBTYPE VFT2_UNKNOWN BEGIN BLOCK StringFileInfo BEGIN BLOCK 040904b0 BEGIN VALUE BuildDate, BUILD_DATE_STR END END END28.2 macOS的Info.plistkeyCFBundleVersion/key string1.0.0.$(date %Y%m%d)/string29. 构建信息数据库在大型系统中集中管理构建信息。29.1 SQLite存储void store_build_info(sqlite3* db) { const char* sql INSERT INTO builds (date, time, version) VALUES (?, ?, ?); sqlite3_stmt* stmt; sqlite3_prepare_v2(db, sql, -1, stmt, NULL); sqlite3_bind_text(stmt, 1, __DATE__, -1, SQLITE_STATIC); sqlite3_bind_text(stmt, 2, __TIME__, -1, SQLITE_STATIC); sqlite3_bind_text(stmt, 3, 1.0.0, -1, SQLITE_STATIC); sqlite3_step(stmt); sqlite3_finalize(stmt); }29.2 远程版本检查void check_latest_version() { // 伪代码 Version local {__DATE__, 1.0.0}; Version remote fetch_latest_version(); if(compare_versions(local, remote) 0) { printf(新版本可用: %s (你的版本: %s)\n, remote.version, local.version); } }30. 构建流水线集成在现代CI/CD流水线中自动化处理构建信息。30.1 Jenkins集成pipeline { environment { BUILD_DATE new Date().format(yyyy-MM-dd) BUILD_TIME new Date().format(HH:mm:ss) } stages { stage(Build) { steps { sh gcc -DBUILD_DATE${BUILD_DATE} -DBUILD_TIME${BUILD_TIME} -o myapp main.c } } } }30.2 GitHub Actions- name: Build run: | echo BUILD_DATE$(date %Y-%m-%d) $GITHUB_ENV echo BUILD_TIME$(date %T) $GITHUB_ENV gcc -DBUILD_DATE$BUILD_DATE -DBUILD_TIME$BUILD_TIME -o myapp main.c31. 构建信息可视化创建仪表板展示构建历史。31.1 简单文本日志void log_build_info() { FILE* f fopen(build.log, a); fprintf(f, %s %s - 构建成功\n, __DATE__, __TIME__); fclose(f); }31.2 HTML报告生成void generate_build_report() { FILE* f fopen(report.html, w); fprintf(f, htmlheadtitle构建报告/title/headbody\n); fprintf(f, h1构建信息/h1\n); fprintf(f, p日期: %s/p\n, __DATE__); fprintf(f, p时间: %s/p\n, __TIME__); fprintf(f, /body/html\n); fclose(f); }32. 构建信息加密在某些场景下可能需要保护构建信息。32.1 简单混淆void print_obfuscated_build_info() { const char* date __DATE__; for(int i0; date[i]; i) { putchar(date[i] ^ 0x55); } putchar(\n); }32.2 AES加密#include openssl/aes.h void encrypt_build_info() { AES_KEY key; unsigned char iv[AES_BLOCK_SIZE]; // 初始化key和iv... unsigned char in[AES_BLOCK_SIZE]; unsigned char out[AES_BLOCK_SIZE]; strncpy((char*)in, __DATE__, AES_BLOCK_SIZE); AES_cbc_encrypt(in, out, AES_BLOCK_SIZE, key, iv, AES_ENCRYPT); // 存储或传输加密后的数据 save_encrypted_data(out, AES_BLOCK_SIZE); }33. 构建信息压缩在空间受限环境中减小体积。33.1 紧凑编码uint32_t compress_date() { char month[4]; int day, year; sscanf(__DATE__, %s %d %d, month, day, year); int month_num ...; // 同前 return (year 9) | (month_num 5) | day; }33.2 Base64编码#include openssl/bio.h #include openssl/evp.h char* base64_encode(const char* input) { BIO* b64 BIO_new(BIO_f_base64()); BIO* mem BIO_new(BIO_s_mem()); BIO_push(b64, mem); BIO_write(b64, input, strlen(input)); BIO_flush(b64); char* output; long len BIO_get_mem_data(mem, output); char* result strndup(output, len); BIO_free_all(b64); return result; }34. 构建信息签名确保构建信息未被篡改。34.1 HMAC签名#include openssl/hmac.h void sign_build_info() { const char* key secret; unsigned char* hmac HMAC(EVP_

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价