C# 如何将基数为10(十进制)的字符串直接转换为C中的字节数组?
我希望获取一个可变长度的字符串输入,对其进行数字解释,并将其解析为一个字节数组,同时对其长度施加任何限制 我已经完成了二进制和十六进制:C# 如何将基数为10(十进制)的字符串直接转换为C中的字节数组?,c#,string,bytearray,base,radix,C#,String,Bytearray,Base,Radix,我希望获取一个可变长度的字符串输入,对其进行数字解释,并将其解析为一个字节数组,同时对其长度施加任何限制 我已经完成了二进制和十六进制: public static byte[] GetHexBytes(this string hex, bool preTrimmed = false) { if (!preTrimmed) { hex = hex.Trim(); if (hex.StartsWith("0x", StringCo
public static byte[] GetHexBytes(this string hex, bool preTrimmed = false)
{
if (!preTrimmed)
{
hex = hex.Trim();
if (hex.StartsWith("0x", StringComparison.OrdinalIgnoreCase))
hex = hex.Substring(2);
else if (hex.StartsWith("16#"))
hex = hex.Substring(3);
}
if (hex.Length % 2 != 0) hex = hex.PadLeft(hex.Length + 1, '0');
return Enumerable.Range(0, hex.Length)
.Where(x => x % 2 == 0)
.Select(x => Convert.ToByte(hex.Substring(x, 2), 16))
.ToArray();
}
public static byte[] GetBinaryBytes(this string binary, bool preTrimmed = false)
{
if (!preTrimmed)
{
binary = binary.Trim();
if (binary.StartsWith("0b", StringComparison.OrdinalIgnoreCase) || binary.StartsWith("2#"))
binary = binary.Substring(2);
}
if (binary.Length % 8 != 0) binary = binary.PadLeft(binary.Length + 8 - binary.Length % 8, '0');
return Enumerable.Range(0, binary.Length)
.Where(x => x % 8 == 0)
.Select(x => Convert.ToByte(binary.Substring(x, 8), 2))
.ToArray();
}
public static byte[] GetDecimalBytes(this string dec, bool preTrimmed = false)
{
if (!preTrimmed)
{
dec = dec.Trim();
if (dec.StartsWith("10#"))
dec = dec.Substring(3);
}
//???
}
是否可以以类似于十六进制和二进制版本(从字符串开头开始,向前工作)的方式进行这种转换
如果不是,是否可以在不使用System.Numerics或BigInteger(从字符串手动执行)的情况下,以不对字符串长度施加任何限制的方式反向执行
我希望它能够处理任何字符串长度,最大字符串长度为C#(1073741823)
例子
我忍不住要为这个问题找到一个可行的解决方案。然而,正如我已经评论过的,直接调用该方法有点言过其实,并且给出的代码没有更有效的输入验证 我的基本方法如下:
- 使用的方法:
value*10==value*(8+2)=(value {
res[bitpos/8]|=(字节)(15年后,但这可能会帮助其他人:public static byte[] GetHexBytes(this string hex) { return BigInteger.Parse(hex, System.Globalization.NumberStyles.HexNumber).ToByteArray(true); } public static byte[] GetDecimalBytes(this string dec) { return BigInteger.Parse(dec).ToByteArray(true); } // Example: using System.Numerics; byte[] inHex = "FFFF".GetHexBytes(); // => [ 0xFF, 0xFF ] byte[] inDec = "65535".GetDecimalBytes(); // => [ 0xFF, 0xFF ]
如果我理解你的意思,你可以通过
将字符串转换为字节数组。举个输入和输出的例子吧?我得到的印象是,你希望得到这样的结果,例如byte[]byteKey=System.Text.ascienceoding.ASCII.GetBytes(“你的字符串”)
,因为“0xFFFFFFFF”。GetHexBytes()=“4294967295”。GetDecimalBytes()
。这自然会扩展到其他值。这种印象正确吗?更好的是,看看。与参考源不同,CoreFX的许可证允许您根据自己的需要调整代码。0xFFFFFFFF==4294967295
内部以非常接近您需要的格式存储值。它应该要求ire仅对提取数字解析进行最小更改,以使用BigInteger
数组,而不是字节
数组。不能以从左到右的方式处理十进制数字,因为10不是二的幂,并且只有在处理开始后才发现所携带的位。从左到右处理的原因是二进制,八进制和十六进制是指没有依赖右侧数据的未使用位尚未处理。您可以使用缓冲区数组缓存位,但这需要缓冲区与原始字符串一样大(在最坏的情况下)所以这不值得。既然你对linq了解很多,你能看看我是如何实现GetOctalBytes的(有点基于你的例子)并给我一些提示吗?“256”。ToDecimalBytes()=>索引超出了数组的界限。@Ehryk已修复。抱歉,昨天有点晚了,所以我在计算时没有检查所有的情况,字节数组长度应该是输入字符串长度的一半。@Ehryk关于uint
函数:这有点离题,所以如果你愿意,你可能想开始一个关于CodeReview的问题你需要反馈。不过我可以给你一个指针:如果你使用GetOctalBytes
重载,你应该能够一次计算你的字节数组位置,而不是通过bool数组。问问题:.SelectMany((元素,索引)=>{…})
// example input string input = "6524562164126412641206685"; var result = input // interpret the string as a list of digits with position .Reverse() // transfer from list of positioned digits to list of actual bit positions, // by repeatedly multiplying with 10 // the resulting bits need to be added for the final result .SelectMany((x, i) => { // digit value var val1 = x - '0'; var res1 = new List<int>(); // to bit positions, as if it was the first digit for (int j = 0; j < 8; j++) { if ((val1 & (1 << j)) != 0) res1.Add(j); } // to absolute bit positions, taking the digit position into account for (int j = 1; j <= i; j++) { var res = new List<int>(); // multiply by 10, until actual position is reached foreach (var item in res1) { res.Add(item + 1); res.Add(item + 3); } // compress bits res1 = res.Aggregate(new HashSet<int>(), (set, i1) => { // two bits in the same position add up to one bit in a higher position while (set.Contains(i1)) { set.Remove(i1); i1++; } set.Add(i1); return set; }).ToList(); } return res1; }). // final elimination of duplicate bit indices Aggregate(new HashSet<int>(), (set, i) => { while (set.Contains(i)) { set.Remove(i); i++; } set.Add(i); return set; }) // transfer bit positions into a byte array - lowest bit is the last bit of the first byte .Aggregate(new byte[(long)Math.Ceiling(input.Length / 2.0)], (res, bitpos) => { res[bitpos / 8] |= (byte)(1 << (bitpos % 8)); return res; });
public static byte[] GetHexBytes(this string hex) { return BigInteger.Parse(hex, System.Globalization.NumberStyles.HexNumber).ToByteArray(true); } public static byte[] GetDecimalBytes(this string dec) { return BigInteger.Parse(dec).ToByteArray(true); } // Example: using System.Numerics; byte[] inHex = "FFFF".GetHexBytes(); // => [ 0xFF, 0xFF ] byte[] inDec = "65535".GetDecimalBytes(); // => [ 0xFF, 0xFF ]