diff --git a/code_templates/dump_title_infos.c b/code_templates/dump_title_infos.c
index eddab1d..3f08fef 100644
--- a/code_templates/dump_title_infos.c
+++ b/code_templates/dump_title_infos.c
@@ -23,7 +23,7 @@
for(u32 j = 0; j < g_titleInfo[i].content_count; j++)
{
char content_id_str[SHA256_HASH_SIZE + 1] = {0};
- utilsGenerateHexStringFromData(content_id_str, sizeof(content_id_str), g_titleInfo[i].content_infos[j].content_id.c, SHA256_HASH_SIZE / 2);
+ utilsGenerateHexStringFromData(content_id_str, sizeof(content_id_str), g_titleInfo[i].content_infos[j].content_id.c, sizeof(g_titleInfo[i].content_infos[j].content_id.c), false);
u64 content_size = 0;
titleConvertNcmContentSizeToU64(g_titleInfo[i].content_infos[j].size, &content_size);
diff --git a/code_templates/sd_romfs_dumper.c b/code_templates/sd_romfs_dumper.c
index 47cfc93..467f833 100644
--- a/code_templates/sd_romfs_dumper.c
+++ b/code_templates/sd_romfs_dumper.c
@@ -288,7 +288,7 @@ u8 get_program_id_offset(TitleInfo *info, u32 program_count)
for(u32 i = scroll; i < program_count; i++)
{
if (i >= (scroll + page_size)) break;
- utilsGenerateHexStringFromData(nca_id_str, sizeof(nca_id_str), content_infos[i]->content_id.c, SHA256_HASH_SIZE / 2);
+ utilsGenerateHexStringFromData(nca_id_str, sizeof(nca_id_str), content_infos[i]->content_id.c, sizeof(content_infos[i]->content_id.c), false);
printf("%s%s.nca (ID offset #%u)\n", i == selected_idx ? " -> " : " ", nca_id_str, content_infos[i]->id_offset);
}
diff --git a/code_templates/system_title_dumper.c b/code_templates/system_title_dumper.c
index 69cd6e9..95d499a 100644
--- a/code_templates/system_title_dumper.c
+++ b/code_templates/system_title_dumper.c
@@ -343,7 +343,7 @@ int main(int argc, char *argv[])
} else
if (menu == 1)
{
- utilsGenerateHexStringFromData(nca_id_str, sizeof(nca_id_str), cur_title_info->content_infos[i].content_id.c, SHA256_HASH_SIZE / 2);
+ utilsGenerateHexStringFromData(nca_id_str, sizeof(nca_id_str), cur_title_info->content_infos[i].content_id.c, sizeof(cur_title_info->content_infos[i].content_id.c), false);
printf("%s (%s)\n", nca_id_str, titleGetNcmContentTypeName(cur_title_info->content_infos[i].content_type));
} else
if (menu == 2)
@@ -376,7 +376,7 @@ int main(int argc, char *argv[])
if (menu == 1)
{
nca_idx = selected_idx;
- utilsGenerateHexStringFromData(nca_id_str, sizeof(nca_id_str), cur_title_info->content_infos[nca_idx].content_id.c, SHA256_HASH_SIZE / 2);
+ utilsGenerateHexStringFromData(nca_id_str, sizeof(nca_id_str), cur_title_info->content_infos[nca_idx].content_id.c, sizeof(cur_title_info->content_infos[nca_idx].content_id.c), false);
}
menu++;
diff --git a/code_templates/usb_romfs_dumper.c b/code_templates/usb_romfs_dumper.c
index 5159d74..91db974 100644
--- a/code_templates/usb_romfs_dumper.c
+++ b/code_templates/usb_romfs_dumper.c
@@ -267,7 +267,7 @@ u8 get_program_id_offset(TitleInfo *info, u32 program_count)
for(u32 i = scroll; i < program_count; i++)
{
if (i >= (scroll + page_size)) break;
- utilsGenerateHexStringFromData(nca_id_str, sizeof(nca_id_str), content_infos[i]->content_id.c, SHA256_HASH_SIZE / 2);
+ utilsGenerateHexStringFromData(nca_id_str, sizeof(nca_id_str), content_infos[i]->content_id.c, sizeof(content_infos[i]->content_id.c), false);
printf("%s%s.nca (ID offset #%u)\n", i == selected_idx ? " -> " : " ", nca_id_str, content_infos[i]->id_offset);
}
diff --git a/include/core/nxdt_utils.h b/include/core/nxdt_utils.h
index ebad338..a625265 100644
--- a/include/core/nxdt_utils.h
+++ b/include/core/nxdt_utils.h
@@ -77,8 +77,9 @@ void utilsReplaceIllegalCharacters(char *str, bool ascii_only);
/// Trims whitespace characters from the provided string.
void utilsTrimString(char *str);
-/// Generates a lowercase hex string representation of the binary data stored in 'src' and stores it in 'dst'.
-void utilsGenerateHexStringFromData(char *dst, size_t dst_size, const void *src, size_t src_size);
+/// Generates a hex string representation of the binary data stored in 'src' and stores it in 'dst'.
+/// If 'uppercase' is true, uppercase characters will be used to generate the hex string. Otherwise, lowercase characters will be used.
+void utilsGenerateHexStringFromData(char *dst, size_t dst_size, const void *src, size_t src_size, bool uppercase);
/// Formats the provided 'size' value to a human-readable size string and stores it in 'dst'.
void utilsGenerateFormattedSizeString(u64 size, char *dst, size_t dst_size);
diff --git a/source/core/cert.c b/source/core/cert.c
index 4332095..9b8dbe9 100644
--- a/source/core/cert.c
+++ b/source/core/cert.c
@@ -146,7 +146,7 @@ u8 *certRetrieveRawCertificateChainFromGameCardByRightsId(const FsRightsId *id,
u8 *raw_chain = NULL;
bool success = false;
- utilsGenerateHexStringFromData(raw_chain_filename, sizeof(raw_chain_filename), id->c, 0x10);
+ utilsGenerateHexStringFromData(raw_chain_filename, sizeof(raw_chain_filename), id->c, sizeof(id->c), false);
strcat(raw_chain_filename, ".cert");
if (!gamecardGetHashFileSystemEntryInfoByName(GameCardHashFileSystemPartitionType_Secure, raw_chain_filename, &raw_chain_offset, &raw_chain_size))
diff --git a/source/core/cnmt.c b/source/core/cnmt.c
index 938bdfc..9c89e04 100644
--- a/source/core/cnmt.c
+++ b/source/core/cnmt.c
@@ -434,7 +434,7 @@ bool cnmtGenerateAuthoringToolXml(ContentMetaContext *cnmt_ctx, NcaContext *nca_
cur_nca_ctx->id_offset)) goto end;
}
- utilsGenerateHexStringFromData(digest_str, sizeof(digest_str), cnmt_ctx->digest, CNMT_DIGEST_SIZE);
+ utilsGenerateHexStringFromData(digest_str, sizeof(digest_str), cnmt_ctx->digest, CNMT_DIGEST_SIZE, false);
if (!utilsAppendFormattedStringToBuffer(&xml_buf, &xml_buf_size, \
" \n" \
diff --git a/source/core/nacp.c b/source/core/nacp.c
index 0cfe22d..a106240 100644
--- a/source/core/nacp.c
+++ b/source/core/nacp.c
@@ -583,7 +583,7 @@ bool nacpGenerateAuthoringToolXml(NacpContext *nacp_ctx, u32 version, u32 requir
sha256CalculateHash(icon_hash, icon_ctx->icon_data, icon_ctx->icon_size);
/* Generate icon hash string. Only the first half from the hash is used. */
- utilsGenerateHexStringFromData(icon_hash_str, SHA256_HASH_SIZE + 1, icon_hash, SHA256_HASH_SIZE / 2);
+ utilsGenerateHexStringFromData(icon_hash_str, sizeof(icon_hash_str), icon_hash, sizeof(icon_hash) / 2, false);
/* Add XML element. */
if (!utilsAppendFormattedStringToBuffer(&xml_buf, &xml_buf_size, \
@@ -690,7 +690,7 @@ bool nacpGenerateAuthoringToolXml(NacpContext *nacp_ctx, u32 version, u32 requir
if (!utilsAppendFormattedStringToBuffer(&xml_buf, &xml_buf_size, " \n")) goto end;
/* SendGroupConfiguration. */
- utilsGenerateHexStringFromData(key_str, sizeof(key_str), ndcc->send_group_configuration.key, sizeof(ndcc->send_group_configuration.key));
+ utilsGenerateHexStringFromData(key_str, sizeof(key_str), ndcc->send_group_configuration.key, sizeof(ndcc->send_group_configuration.key), false);
if (!utilsAppendFormattedStringToBuffer(&xml_buf, &xml_buf_size, \
" \n" \
@@ -705,7 +705,7 @@ bool nacpGenerateAuthoringToolXml(NacpContext *nacp_ctx, u32 version, u32 requir
{
NacpApplicationNeighborDetectionGroupConfiguration *rgc = &(ndcc->receivable_group_configurations[i]);
- utilsGenerateHexStringFromData(key_str, sizeof(key_str), rgc->key, sizeof(rgc->key));
+ utilsGenerateHexStringFromData(key_str, sizeof(key_str), rgc->key, sizeof(rgc->key), false);
if (!utilsAppendFormattedStringToBuffer(&xml_buf, &xml_buf_size, \
" \n" \
diff --git a/source/core/nca.c b/source/core/nca.c
index bc0a673..78f97b3 100644
--- a/source/core/nca.c
+++ b/source/core/nca.c
@@ -101,9 +101,9 @@ bool ncaInitializeContext(NcaContext *out, u8 storage_id, u8 hfs_partition_type,
out->ncm_storage = (out->storage_id != NcmStorageId_GameCard ? ncm_storage : NULL);
memcpy(&(out->content_id), &(content_info->content_id), sizeof(NcmContentId));
- utilsGenerateHexStringFromData(out->content_id_str, sizeof(out->content_id_str), out->content_id.c, sizeof(out->content_id.c));
+ utilsGenerateHexStringFromData(out->content_id_str, sizeof(out->content_id_str), out->content_id.c, sizeof(out->content_id.c), false);
- utilsGenerateHexStringFromData(out->hash_str, sizeof(out->hash_str), out->hash, sizeof(out->hash)); /* Placeholder, needs to be manually calculated. */
+ utilsGenerateHexStringFromData(out->hash_str, sizeof(out->hash_str), out->hash, sizeof(out->hash), false); /* Placeholder, needs to be manually calculated. */
out->content_type = content_info->content_type;
out->id_offset = content_info->id_offset;
@@ -499,11 +499,11 @@ void ncaUpdateContentIdAndHash(NcaContext *ctx, u8 hash[SHA256_HASH_SIZE])
/* Update content ID. */
memcpy(ctx->content_id.c, hash, sizeof(ctx->content_id.c));
- utilsGenerateHexStringFromData(ctx->content_id_str, sizeof(ctx->content_id_str), ctx->content_id.c, sizeof(ctx->content_id.c));
+ utilsGenerateHexStringFromData(ctx->content_id_str, sizeof(ctx->content_id_str), ctx->content_id.c, sizeof(ctx->content_id.c), false);
/* Update content hash. */
memcpy(ctx->hash, hash, sizeof(ctx->hash));
- utilsGenerateHexStringFromData(ctx->hash_str, sizeof(ctx->hash_str), ctx->hash, sizeof(ctx->hash));
+ utilsGenerateHexStringFromData(ctx->hash_str, sizeof(ctx->hash_str), ctx->hash, sizeof(ctx->hash), false);
}
const char *ncaGetFsSectionTypeName(NcaFsSectionContext *ctx)
diff --git a/source/core/nxdt_log.c b/source/core/nxdt_log.c
index a81dae6..0725185 100644
--- a/source/core/nxdt_log.c
+++ b/source/core/nxdt_log.c
@@ -142,7 +142,7 @@ __attribute__((format(printf, 4, 5))) void logWriteBinaryDataToLogFile(const voi
if (!data_str) goto end;
/* Generate hex string representation. */
- utilsGenerateHexStringFromData(data_str, data_str_size, data, data_size);
+ utilsGenerateHexStringFromData(data_str, data_str_size, data, data_size, true);
strcat(data_str, g_logLineBreak);
/* Write formatted string. */
diff --git a/source/core/nxdt_utils.c b/source/core/nxdt_utils.c
index b91af26..3a3a9b3 100644
--- a/source/core/nxdt_utils.c
+++ b/source/core/nxdt_utils.c
@@ -448,7 +448,7 @@ void utilsTrimString(char *str)
if (start != str) memmove(str, start, end - start + 1);
}
-void utilsGenerateHexStringFromData(char *dst, size_t dst_size, const void *src, size_t src_size)
+void utilsGenerateHexStringFromData(char *dst, size_t dst_size, const void *src, size_t src_size, bool uppercase)
{
if (!src || !src_size || !dst || dst_size < ((src_size * 2) + 1)) return;
@@ -460,8 +460,8 @@ void utilsGenerateHexStringFromData(char *dst, size_t dst_size, const void *src,
char h_nib = ((src_u8[i] >> 4) & 0xF);
char l_nib = (src_u8[i] & 0xF);
- dst[j++] = (h_nib + (h_nib < 0xA ? 0x30 : 0x57));
- dst[j++] = (l_nib + (l_nib < 0xA ? 0x30 : 0x57));
+ dst[j++] = (h_nib + (h_nib < 0xA ? 0x30 : (uppercase ? 0x37 : 0x57)));
+ dst[j++] = (l_nib + (l_nib < 0xA ? 0x30 : (uppercase ? 0x37 : 0x57)));
}
dst[j] = '\0';
diff --git a/source/core/tik.c b/source/core/tik.c
index 518f131..c0befa7 100644
--- a/source/core/tik.c
+++ b/source/core/tik.c
@@ -145,7 +145,7 @@ bool tikRetrieveTicketByRightsId(Ticket *dst, const FsRightsId *id, bool use_gam
/* Generate rights ID string. */
tik_common_block = tikGetCommonBlock(dst->data);
- utilsGenerateHexStringFromData(dst->rights_id_str, sizeof(dst->rights_id_str), tik_common_block->rights_id.c, sizeof(tik_common_block->rights_id.c));
+ utilsGenerateHexStringFromData(dst->rights_id_str, sizeof(dst->rights_id_str), tik_common_block->rights_id.c, sizeof(tik_common_block->rights_id.c), false);
return true;
}
@@ -237,7 +237,7 @@ static bool tikRetrieveTicketFromGameCardByRightsId(Ticket *dst, const FsRightsI
char tik_filename[0x30] = {0};
u64 tik_offset = 0, tik_size = 0;
- utilsGenerateHexStringFromData(tik_filename, sizeof(tik_filename), id->c, 0x10);
+ utilsGenerateHexStringFromData(tik_filename, sizeof(tik_filename), id->c, sizeof(id->c), false);
strcat(tik_filename, ".tik");
if (!gamecardGetHashFileSystemEntryInfoByName(GameCardHashFileSystemPartitionType_Secure, tik_filename, &tik_offset, &tik_size))