-
-
Notifications
You must be signed in to change notification settings - Fork 7
feat(Converter): add HexConverter/BinConverter static class #544
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
f4bd614
ef43651
a3975ee
bb6a651
76f2b86
e23d095
cefb932
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,59 @@ | ||||||||||||||||||||||||||||||||||||||||
| // Copyright (c) BootstrapBlazor & Argo Zhang (argo@live.ca). All rights reserved. | ||||||||||||||||||||||||||||||||||||||||
| // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. | ||||||||||||||||||||||||||||||||||||||||
| // Website: https://www.blazor.zone or https://argozhang.github.io/ | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| using System.Text; | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| namespace BootstrapBlazor.Components.DataConverter; | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| /// <summary> | ||||||||||||||||||||||||||||||||||||||||
| /// 二进制 与 Byte 数组转换方法 | ||||||||||||||||||||||||||||||||||||||||
| /// </summary> | ||||||||||||||||||||||||||||||||||||||||
| public static class BinConverter | ||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||
| /// <summary> | ||||||||||||||||||||||||||||||||||||||||
| /// 将 byte[] 转为 二进制字符串 | ||||||||||||||||||||||||||||||||||||||||
| /// <para>Converts a byte array to its hexadecimal string representation.</para> | ||||||||||||||||||||||||||||||||||||||||
| /// </summary> | ||||||||||||||||||||||||||||||||||||||||
| /// <param name="bytes">The byte array to convert.</param> | ||||||||||||||||||||||||||||||||||||||||
| /// <param name="separator"></param> | ||||||||||||||||||||||||||||||||||||||||
| /// <returns>A string containing the hexadecimal representation of the byte array.</returns> | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
| /// <returns>A string containing the hexadecimal representation of the byte array.</returns> | |
| /// <returns>A string containing the binary representation of the byte array.</returns> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion (bug_risk): Padding each split segment to 8 may mask input errors.
Validate segment lengths before padding to prevent masking malformed input.
| // 把 str 内的 separator 符号替换掉 | |
| if (!string.IsNullOrEmpty(separator)) | |
| { | |
| str = string.Join("", str.Split(separator, options).Select(i => i.PadLeft(8, '0'))); | |
| } | |
| // 把 str 内的 separator 符号替换掉 | |
| if (!string.IsNullOrEmpty(separator)) | |
| { | |
| var segments = str.Split(separator, options); | |
| const int expectedLength = 8; | |
| foreach (var segment in segments) | |
| { | |
| if (segment.Length > expectedLength) | |
| { | |
| throw new FormatException($"Segment '{segment}' length {segment.Length} exceeds expected length {expectedLength}."); | |
| } | |
| } | |
| str = string.Join("", segments.Select(i => i.PadLeft(expectedLength, '0'))); | |
| } |
Copilot
AI
Aug 27, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comment incorrectly refers to 'Hex 形式的 str' (Hex format string) when it should refer to binary format string in the BinConverter class.
| // 把 Hex 形式的 str 转化为 byte[] | |
| // 把二进制形式的 str 转化为 byte[] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nitpick: Exception message refers to 'odd number of digits' for binary conversion.
Update the exception message to specify that the string length must be a multiple of 8 for binary conversion.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,70 @@ | ||
| // Copyright (c) BootstrapBlazor & Argo Zhang (argo@live.ca). All rights reserved. | ||
| // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. | ||
| // Website: https://www.blazor.zone or https://argozhang.github.io/ | ||
|
|
||
| using System.Text; | ||
|
|
||
| namespace BootstrapBlazor.Components.DataConverter; | ||
|
|
||
| /// <summary> | ||
| /// 十六进制 与 Byte 数组转换方法 | ||
| /// </summary> | ||
| public static class HexConverter | ||
| { | ||
| /// <summary> | ||
| /// 将 byte[] 转为 16 进制字符串 | ||
| /// <para>Converts a byte array to its hexadecimal string representation.</para> | ||
| /// </summary> | ||
| /// <param name="bytes">The byte array to convert.</param> | ||
| /// <param name="separator"></param> | ||
| /// <returns>A string containing the hexadecimal representation of the byte array.</returns> | ||
| public static string ToString(byte[]? bytes, string? separator = "-") | ||
| { | ||
| if (bytes == null || bytes.Length == 0) | ||
| { | ||
| return string.Empty; | ||
| } | ||
|
|
||
| if (separator == "-") | ||
| { | ||
| return BitConverter.ToString(bytes); | ||
| } | ||
|
|
||
| var sb = new StringBuilder(bytes.Length * 3); | ||
| foreach (var b in bytes) | ||
| { | ||
| sb.Append(b.ToString("X2")); | ||
| sb.Append(separator); | ||
| } | ||
| return sb.ToString(0, sb.Length - 1); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. issue: Potential issue if separator is an empty string. When separator is empty, the current logic omits the last byte. Please add a condition to handle empty separators to ensure correct output. |
||
| } | ||
|
|
||
| /// <summary> | ||
| /// 将字符串转换为字节数组 | ||
| /// </summary> | ||
| /// <param name="str"></param> | ||
| /// <param name="separator"></param> | ||
| /// <param name="options"></param> | ||
| /// <returns></returns> | ||
| public static byte[] ToBytes(string str, string? separator = null, StringSplitOptions options = StringSplitOptions.None) | ||
| { | ||
| // 把 str 内的 delimiter 符号替换掉 | ||
| if (!string.IsNullOrEmpty(separator)) | ||
| { | ||
| str = string.Join("", str.Split(separator, options)); | ||
| } | ||
|
|
||
| // 把 Hex 形式的 str 转化为 byte[] | ||
| if (str.Length % 2 != 0) | ||
| { | ||
| throw new ArgumentException("The raw string cannot have an odd number of digits. 参数 str 位数不正确无法转化为 16 进制字节数组", nameof(str)); | ||
| } | ||
|
|
||
| var bytes = new byte[str.Length / 2]; | ||
| for (var i = 0; i < bytes.Length; i++) | ||
| { | ||
| bytes[i] = Convert.ToByte(str.Substring(i * 2, 2), 16); | ||
| } | ||
| return bytes; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,57 @@ | ||
| // Copyright (c) BootstrapBlazor & Argo Zhang (argo@live.ca). All rights reserved. | ||
| // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. | ||
| // Website: https://www.blazor.zone or https://argozhang.github.io/ | ||
|
|
||
| using BootstrapBlazor.Components.DataConverter; | ||
|
|
||
| namespace UnitTestTcpSocket; | ||
|
|
||
| public class BinConverterTest | ||
| { | ||
| [Fact] | ||
| public void ToHexString_Null() | ||
| { | ||
| var actual = BinConverter.ToString(null); | ||
| Assert.Equal(string.Empty, actual); | ||
|
|
||
| actual = BinConverter.ToString([]); | ||
| Assert.Equal(string.Empty, actual); | ||
| } | ||
|
|
||
|
Comment on lines
+11
to
+20
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. suggestion (testing): Exception test does not cover valid binary string with odd length. Please add a test for a raw binary string with odd length, such as "0001101", to verify the exception is correctly thrown in this case. |
||
| [Fact] | ||
| public void ToBinString_Ok() | ||
| { | ||
| var data = new byte[] { 0x1A, 0x02 }; | ||
| var actual = BinConverter.ToString(data); | ||
| Assert.Equal("00011010-00000010", actual); | ||
|
|
||
| actual = BinConverter.ToString(data, " "); | ||
| Assert.Equal("00011010 00000010", actual); | ||
| } | ||
|
|
||
| [Fact] | ||
| public void ToHexString_Exception() | ||
| { | ||
| var data = "00011010-00000010"; | ||
| var ex = Assert.ThrowsAny<ArgumentException>(() => BinConverter.ToBytes(data)); | ||
| Assert.NotNull(ex); | ||
| } | ||
|
|
||
| [Fact] | ||
| public void ToBytes_Ok() | ||
| { | ||
| var excepted = new byte[] { 0x1A, 0x02 }; | ||
|
|
||
| var data = "00011010-00000010"; | ||
| var actual = BinConverter.ToBytes(data, "-"); | ||
| Assert.Equal(excepted, actual); | ||
|
|
||
| data = "00011010 00000010"; | ||
| actual = BinConverter.ToBytes(data, " "); | ||
| Assert.Equal(excepted, actual); | ||
|
|
||
| data = "0001101000000010"; | ||
| actual = BinConverter.ToBytes(data); | ||
| Assert.Equal(excepted, actual); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,57 @@ | ||
| // Copyright (c) BootstrapBlazor & Argo Zhang (argo@live.ca). All rights reserved. | ||
| // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. | ||
| // Website: https://www.blazor.zone or https://argozhang.github.io/ | ||
|
|
||
| using BootstrapBlazor.Components.DataConverter; | ||
|
|
||
| namespace UnitTestTcpSocket; | ||
|
|
||
| public class HexConverterTest | ||
| { | ||
| [Fact] | ||
| public void ToHexString_Null() | ||
| { | ||
| var actual = HexConverter.ToString(null); | ||
| Assert.Equal(string.Empty, actual); | ||
|
|
||
| actual = HexConverter.ToString([]); | ||
| Assert.Equal(string.Empty, actual); | ||
| } | ||
|
|
||
|
Comment on lines
+11
to
+20
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. suggestion (testing): Exception test does not cover valid hex string with odd length and with separators. Please add a test with a hex string containing separators that results in an odd digit count after removing separators, to verify the exception is correctly thrown in this case. |
||
| [Fact] | ||
| public void ToHexString_Exception() | ||
| { | ||
| var data = "1A021304FE1"; | ||
| var ex = Assert.ThrowsAny<ArgumentException>(() => HexConverter.ToBytes(data)); | ||
| Assert.NotNull(ex); | ||
| } | ||
|
|
||
| [Fact] | ||
| public void ToHexString_Ok() | ||
| { | ||
| var data = new byte[] { 0x1A, 0x02, 0x13, 0x04, 0xFE }; | ||
| var actual = HexConverter.ToString(data); | ||
| Assert.Equal("1A-02-13-04-FE", actual); | ||
|
|
||
| actual = HexConverter.ToString(data, " "); | ||
| Assert.Equal("1A 02 13 04 FE", actual); | ||
| } | ||
|
|
||
| [Fact] | ||
| public void ToBytes_Ok() | ||
| { | ||
| var excepted = new byte[] { 0x1A, 0x02, 0x13, 0x04, 0xFE }; | ||
|
|
||
| var data = "1A021304FE"; | ||
| var actual = HexConverter.ToBytes(data); | ||
| Assert.Equal(excepted, actual); | ||
|
|
||
| data = "1A-02-13-04-FE"; | ||
| actual = HexConverter.ToBytes(data, "-"); | ||
| Assert.Equal(excepted, actual); | ||
|
|
||
| data = "1A 02 13 04 FE"; | ||
| actual = HexConverter.ToBytes(data, " "); | ||
| Assert.Equal(excepted, actual); | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The documentation comment incorrectly states 'hexadecimal string representation' when it should be 'binary string representation' for the BinConverter class.