net core中byte数组如何高效转换为16进制字符串

news2024/9/24 21:22:03

在 .NET Core 中,如何把 byte[] 转换为 16 进制字符串?你能想到哪些方法?什么方式性能最好?今天和大家分享几种转换方式。

往往在处理字符串性能问题时,首先应该想到的是怎么想办法减少内存分配,怎么优化字符串构建。

下面就通过递进的方式介绍几种实现方式。

1. 使用 StringBuilder

在需要做大量字符串拼接的场景中,我们首先就会想到StringBuilder,相比string类型来说StringBuilder更高效。在这个例子中,它通过一次性分配足够的内存,然后配合字节格式化方法AppendFormat进行转换,并逐个追加每个字节的 16 进制表示,以此减少内存分配的开销。

using System;
using System.Text;
public class BytesToHexString
{
    public static string ToHexStringStringBuilder(byte[] bytes)
    {
      StringBuilder hex = new StringBuilder(bytes.Length * 2);
      foreach (byte b in bytes)
      {
          hex.AppendFormat("{0:x2}", b);
      }
      return hex.ToString();
    }
}

下面我们使用Benchmark对ToHexStringStringBuilder方法进行些基准测试,分别对字节数组长度为100、1000、10000个元素分别进行10000次测试,然后进行横向对比。

可以发现这个方法随着数组长度增加整体性能是在下降的。

2. 使用 BitConverter

BitConverter 是 .NET 中的内置类,它提供了一种简单的方式来转换基础数据类型为字符串。代码非常简洁,但是其本身只能输出固定格式如“0A-BC-99”,有连接符“-”并且字母都是大写,因此只适合简单需求,如果有复杂要求还行额外单独处理。

using System;
public class BytesToHexString
{
    public static string ToHexStringBitConverter (byte[] bytes)
    {
        return BitConverter.ToString(bytes);
    }
}

下面我们再次使用Benchmark对ToHexStringBitConverter方法进行些基准测试,分别对字节数组长度为100、1000、10000个元素各进行10000次测试,进行横向对比。

StringBuilder方式对比,性能得到大幅度提升。

3. 使用 Convert(.NET5+)

Convert是 .NET 中的内置类,Convert.ToHexString是在 .NET 5 中引入的方法,用于将字节数组直接转换为十六进制字符串,改方法设计之初就考虑了性能,它在实现上减少了额外的内存分配和操作,因此它比 BitConverter.ToString 更高效。但是其本身只能输出固定格式如“0ABC99”,没有连接符“-”并且字母都是大写。

using System;
public class BytesToHexString
{
    public static string ToHexStringConvert (byte[] bytes)
    {
        return Convert.ToHexString (bytes);
    }
}

下面我们再次使用Benchmark对ToHexStringConvert方法进行些基准测试,分别对字节数组长度为100、1000、10000个元素各进行10000次测试,然后进行横向对比。

BitConverter方式对比,性能也是大幅度提升。

4. 使用位运算

在将 byte[] 转换为 16 进制字符串时,每个字节会被转化为两个字符。因此,我们需要一个长度为 bytes.Length * 2 的字符数组来存储最终的 16 进制字符串。同时定义字符串hex = "0123456789abcdef";这个字符串中包含了所有可能的 16 进制字符,接下来遍历循环把每个字节通过位运算分解为2个 4 位的部分(高 4 位和低 4 位),然后通过字符串hex将高4位转为16进制第一个字符,低4位转为第二个字符。以下是一个示例实现:

using System;
public class BytesToHexString
{
    public static string ToHexStringBitOperation (byte[] bytes)
    {
        char[] hexChars = new char[bytes.Length * 2];
        const string hex = "0123456789abcdef";
        for (int i = 0; i < bytes.Length; i++)
        {
            hexChars[i * 2] = hex[bytes[i] >> 4];
            hexChars[i * 2 + 1] = hex[bytes[i] & 0x0F];
        }
        return new string(hexChars);
    }
}

 下面我们再次使用Benchmark对ToHexStringBitOperation方法进行些基准测试,分别对字节数组长度为100、1000、10000个元素各进行10000次测试,然后进行横向对比。

虽然和BitConverter相比,性能提升3倍多,但是和Convert方式相比却有所差距。

如果对位运算不是很明白的,可以留言,后面可以单独出一篇文章讲解一下。

5. 使用 unsafe 代码块(高级)

如果你需要极致的性能,并且可以接受 unsafe 代码,你可以使用指针来操作字节数组。这种方法可以极大地提高性能,但需要注意内存安全问题。

using System;
public class BytesToHexString
{
    public static unsafe string ToHexStringUnsafe(byte[] bytes)
    {
        const string hex = "0123456789ABCDEF";
        var hexChars = new char[bytes.Length * 2];
        fixed (byte* bytePtr = bytes)
        {
            fixed (char* charPtr = hexChars)
            {
                byte* source = bytePtr;
                char* dest = charPtr;
                for (int i = 0; i < bytes.Length; i++)
                {
                    byte b = source[i];
                    dest[i * 2] = hex[b >> 4];
                    dest[i * 2 + 1] = hex[b & 0x0F];
                }
            }
        }
        return new string(hexChars);
    }
}

下面我们再次使用Benchmark对ToHexStringBitConverter方法进行些基准测试,分别对字节数组长度为100、1000、10000个元素各进行10000次测试,然后进行横向对比。

位运算方式相比,并没有像前面的大幅提升,相差无几。

下面看看5种方法,整体对比情况:

通过上面一系列测试,我们可以得到如下总结:

灵活性:StringBuilder、位操作、unsafe 代码块 > BitConverter、Convert

性能:Convert > unsafe 代码块 > 位操作 > BitConverter > StringBuilder

如果只是要把字节数组转化为字符串没有什么要求,那么直接选择官方自带方法Convert.ToHexString;如果对于输出格式有要求,则可以用位操作的方式自己实现个性化需求;当在极端特殊情况下可以考虑unsafe 代码块方式。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2084200.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

22.优化器

优化器 当使用损失函数时&#xff0c;可以调用损失函数的 backward&#xff0c;得到反向传播&#xff0c;反向传播可以求出每个需要调节的参数对应的梯度&#xff0c;有了梯度就可以利用优化器&#xff0c;优化器根据梯度对参数进行调整&#xff0c;以达到整体误差降低的目的。…

Cryptomator:开源云存储加密

采用最新技术标准&#xff0c;提供最佳保护 如果有人查看您云中的文件夹&#xff0c;他们无法对您的数据得出任何结论。 Cryptomator 提供开源的客户端云文件加密。 它适用于 Windows、Linux、macOS 和 iOS。 Cryptomator 可与 Dropbox、Google Drive、OneDrive、MEGA、pClo…

【QT | 开发环境搭建】Linux系统(Ubuntu 18.04) 安装 QT 5.12.12 开发环境

&#x1f601;博客主页&#x1f601;&#xff1a;&#x1f680;https://blog.csdn.net/wkd_007&#x1f680; &#x1f911;博客内容&#x1f911;&#xff1a;&#x1f36d;嵌入式开发、Linux、C语言、C、数据结构、音视频&#x1f36d; ⏰发布时间⏰&#xff1a; 2024-08-29 …

C# 委托详解(Delegate)

引言 在 C# 编程当中&#xff0c;委托&#xff08;Delegate&#xff09;是一种特殊的类型&#xff0c;它允许将方法作为参数传递给其他方法&#xff0c;或者将方法作为返回值返回&#xff0c;这种特性使得委托成为实现回调函数、事件处理等&#xff0c;所有的委托都派生自Syst…

【STM32开发笔记】使用RT-Thread的SDIO驱动和FATFS实现SD卡文件读写

【STM32开发笔记】使用RT-Thread的SDIO驱动和FATFS实现SD卡文件读写 一、准备工作1.1 准备好开发板和SD卡1.2 创建RT-Thread项目 二、配置RT-Thread2.1 打开文件系统相关配置2.2 打开SD卡相关配置2.3 打开RTC配置2.4 重新生成Keil项目文件 三、编译、烧录、运行3.1 编译项目3.2…

网站建设完成后, 营销型网站如何做seo

营销型网站的SEO优化旨在提高网站在搜索引擎中的排名&#xff0c;从而吸引更多潜在客户并促进销售。以下是营销型网站SEO的详细解析&#xff1a; 关键词研究与优化 目标受众分析&#xff1a;了解目标受众的搜索习惯和需求&#xff0c;确定适合的关键词。使用工具来发现相关关键…

RV1126的GPIO计算和使用

1、获取GPIO芯片对应的序号值 先读取下/sys/kernel/debug/gpio的值&#xff0c;得到每个GPIO芯片的序号范围&#xff0c;如GPIO芯片0就为0~31。 2、根据GPIO硬件编号计算出系统内使用的GPIO序号 根据GPIO的编号&#xff0c;比如说GPIO3_B0&#xff0c;前面GPIO3代表看GPIO3的信…

傻瓜操作:GraphRAG、Ollama 本地部署及踩坑记录

目录 一、GraphRAG 介绍1.引言2.创新点3. 算法4. 数据和实验结果5.不足和展望 二、本地部署1.为什么要本地部署2.环境准备3. GraphRAG 安装3.1 下载 GraphGAG3.2 安装依赖包3.3 创建数据目录3.4 项目初始化3.5 修改配置文件 3.6 修改.env文件3.7 修改源码 4. Indexing5. query5…

Linux关于压缩之后文件更大的解释

记录于24年八月29 使用vim命令创建了lianxi1和lianxi2并在里面填写了一些内容&#xff0c;发现使用gzip和zip压缩后文件反而更大 事后问了一下ai回答了我的疑惑 压缩算法开销&#xff1a;如前所述&#xff0c;压缩文件需要存储额外的元数据和文件结构信息。这种开销在处理非常…

C++ TinyWebServer项目总结(13. 多进程编程)

本章讨论Linux多进程编程的以下内容&#xff1a; 复制进程映像的fork系统调用和替换进程映像的exec系列系统调用。僵尸进程以及如何避免僵尸进程。进程间通信&#xff08;Inter Process Communication&#xff0c;IPC&#xff09;最简单的方式&#xff1a;管道。三种System V进…

浏览器插件利器--allWebPluginV2.0.0.18-alpha版发布

allWebPlugin简介 allWebPlugin中间件是一款为用户提供安全、可靠、便捷的浏览器插件服务的中间件产品&#xff0c;致力于将浏览器插件重新应用到所有浏览器。它将现有ActiveX控件直接嵌入浏览器&#xff0c;实现插件加载、界面显示、接口调用、事件回调等。支持Chrome、Firefo…

[MRCTF2020]Unravel!!

使用zsteg查看图片有隐藏文件&#xff0c;没有头绪&#xff0c;先放弃 使用zsteg和010editor查看都发现一个png图片 把JM.png拷贝到kali&#xff0c;使用binwalk分离&#xff0c;得到一个aes.png 使用010editor查看wav&#xff0c;发现尾部有可疑的字符串&#xff0c;拷贝出来备…

记一次应急响应之网站暗链排查

目录 前言 1. 从暗链而起的开端 1.1 暗链的介绍 1.2 暗链的分类 2. 在没有日志的情况下如何分析入侵 2.1 寻找指纹 2.2 搜索引擎搜索fofa资产搜索 2.2.1 fofa资产搜索 2.2.2 bing搜索引擎搜索 3.通过搭建系统并进行漏洞复现 4. 应急响应报告编写 前言 免责声明 博文…

二叉树(binary tree)遍历详解

一、简介 二叉树常见的遍历方式包括前序遍历、中序遍历、后序遍历和层序遍历等。我将以下述二叉树来讲解这几种遍历算法。 1、创建二叉树代码实现 class TreeNode:def __init__(self,data):self.datadataself.leftNoneself.rightNonedef createTree():treeRootTreeNode(F)N…

大模型提示词工程技术3-提示词输入与输出的优化的技巧详细介绍

大模型提示词工程技术3-提示词输入与输出的优化的技巧详细介绍。《大模型提示词工程技术》的作者&#xff1a;微学AI&#xff0c;这是一本专注于提升人工智能大模型性能的著作&#xff0c;它深入浅出地讲解了如何通过优化输入提示词来引导大模型生成高质量、准确的输出。书中不…

腾讯地图三维模型加载GLTF,播放模型动画

腾讯地图三维模型加载&#xff0c;播放模型动画 关键代码 const clock new THREE.Clock();console.log(gltf)// 确保gltf对象包含scene和animations属性if (gltf && gltf.scene && gltf.animations) {// 创建AnimationMixer实例&#xff0c;传入模型的scenec…

【51单片机】2-3-1 【I/O口】【电动车防盗报警项目】震动传感器实验1—震动点灯

1.硬件 51单片机最小系统LED灯模块震动传感器模块 2.软件 main.c程序 #include "reg52.h"sbit led1 P3^7;//根据原理图&#xff08;电路图&#xff09;&#xff0c;设备变量led1指向P3组IO口的第7口 sbit vibrate P3^3;//Do接到了P3.3口void Delay2000ms() //…

力扣刷题--2185. 统计包含给定前缀的字符串【简单】

题目描述 给你一个字符串数组 words 和一个字符串 pref 。 返回 words 中以 pref 作为 前缀 的字符串的数目。 字符串 s 的 前缀 就是 s 的任一前导连续字符串。 示例 1&#xff1a; 输入&#xff1a;words [“pay”,“attention”,“practice”,“attend”], pref “at…

用 Higress AI 网关降低 AI 调用成本 - 阿里云天池云原生编程挑战赛参赛攻略

作者介绍&#xff1a;杨贝宁&#xff0c;爱丁堡大学博士在读&#xff0c;研究方向为向量数据库 《Higress AI 网关挑战赛》正在火热进行中&#xff0c;Higress 社区邀请了目前位于排行榜 top5 的选手杨贝宁同学分享他的心得。下面是他整理的参赛攻略&#xff1a; 背景 我们…

Jmeter(十四)Jmeter分布式部署测试

单个接口测试&#xff0c;我们使用谷歌的插件postman 多个接口测试&#xff0c;我们使用Jmeter进行测试 一、使用工具测试 1、使用Jmeter对接口测试 首先我们说一下为什么用Posman测试后我们还要用Jmeter做接口测试&#xff0c;在用posman测试时候会发现的是一个接口一个接…