Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<Version>9.0.1</Version>
<Version>9.0.2</Version>
</PropertyGroup>

<PropertyGroup>
Expand Down
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>
Comment on lines +16 to +20
Copy link

Copilot AI Aug 27, 2025

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.

Suggested change
/// <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>
/// <para>Converts a byte array to its binary string representation.</para>
/// </summary>
/// <param name="bytes">The byte array to convert.</param>
/// <param name="separator"></param>
/// <returns>A string containing the binary representation of the byte array.</returns>

Copilot uses AI. Check for mistakes.
Copy link

Copilot AI Aug 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The return documentation incorrectly states 'hexadecimal representation' when it should be 'binary representation' for the BinConverter class.

Suggested change
/// <returns>A string containing the hexadecimal representation of the byte array.</returns>
/// <returns>A string containing the binary representation of the byte array.</returns>

Copilot uses AI. Check for mistakes.
public static string ToString(byte[]? bytes, string? separator = "-")
{
if (bytes == null || bytes.Length == 0)
{
return string.Empty;
}

return string.Join(separator, bytes.Select(i => Convert.ToString(i, 2).PadLeft(8, '0')));
}

/// <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 内的 separator 符号替换掉
if (!string.IsNullOrEmpty(separator))
{
str = string.Join("", str.Split(separator, options).Select(i => i.PadLeft(8, '0')));
}
Comment on lines +40 to +44
Copy link
Copy Markdown

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.

Suggested change
// 把 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')));
}


// 把 Hex 形式的 str 转化为 byte[]
Copy link

Copilot AI Aug 27, 2025

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.

Suggested change
// 把 Hex 形式的 str 转化为 byte[]
// 把二进制形式的 str 转化为 byte[]

Copilot uses AI. Check for mistakes.
if (str.Length % 8 != 0)
Copy link
Copy Markdown

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.

{
throw new ArgumentException("The raw string cannot have an odd number of digits. 参数 str 位数不正确无法转化为 二进制字节数组", nameof(str));
}

var bytes = new byte[str.Length / 8];
for (var i = 0; i < bytes.Length; i++)
{
bytes[i] = Convert.ToByte(str.Substring(i * 8, 8), 2);
}
return bytes;
}
}
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);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The 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;
}
}
57 changes: 57 additions & 0 deletions test/UnitTestTcpSocket/BinConverterTest.cs
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
Copy link
Copy Markdown

Choose a reason for hiding this comment

The 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);
}
}
57 changes: 57 additions & 0 deletions test/UnitTestTcpSocket/HexConverterTest.cs
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
Copy link
Copy Markdown

Choose a reason for hiding this comment

The 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);
}
}