C#替换Byte 中的字节

替换字节数组中某些字节的最佳方法是什么?

例如,我有bytesFromServer = listener.Receive(ref groupEP); 我可以做BitConverter.ToString(bytesFromServer)将其转换为可读格式,以返回沿着

 48 65 6c 6c 6f 20 74 68 65 72 65 20 68 65 6c 70 66 75 6c 20 70 65 6f 70 6c 65 

我想将“68 65 6c”中的内容替换成类似“68 00 00”的内容(仅作为示例)。 字节[]上没有.Replace()。

是否有一种简单的方法将其转换回字节[]?

任何帮助赞赏。 谢谢!

你可以编程它….尝试这个开始…然而这不是强大的不生产像代码… …知道一个错误我没有完全测试这…

  public int FindBytes(byte[] src, byte[] find) { int index = -1; int matchIndex = 0; // handle the complete source array for(int i=0; i=0) { dst = new byte[src.Length - search.Length + repl.Length]; // before found array Buffer.BlockCopy(src,0,dst,0, index); // repl copy Buffer.BlockCopy(repl,0,dst,index,repl.Length); // rest of src array Buffer.BlockCopy( src, index+search.Length , dst, index+repl.Length, src.Length-(index+search.Length)); } return dst; } 

实现作为扩展方法

 public void Replace(this byte[] src, byte[] search, byte[] repl) { ReplaceBytes(src, search, repl); } 

使用常规方法:

 ReplaceBytes(bytesfromServer, new byte[] {0x75, 0x83 } , new byte[]{ 0x68, 0x65, 0x6c}); 

扩展方法用法:

 bytesfromServer.Replace( new byte[] {0x75, 0x83 }, new byte[]{ 0x68, 0x65, 0x6c}); 

Array.Copy怎么Array.Copy

改进了rene的代码,我为它创建了一个while循环来替换所有出现的代码:

 public static byte[] ReplaceBytes(byte[] src, byte[] search, byte[] repl) { byte[] dst = null; byte[] temp = null; int index = FindBytes(src, search); while (index >= 0) { if (temp == null) temp = src; else temp = dst; dst = new byte[temp.Length - search.Length + repl.Length]; // before found array Buffer.BlockCopy(temp, 0, dst, 0, index); // repl copy Buffer.BlockCopy(repl, 0, dst, index, repl.Length); // rest of src array Buffer.BlockCopy( temp, index + search.Length, dst, index + repl.Length, temp.Length - (index + search.Length)); index = FindBytes(dst, search); } return dst; } 

这个方法可行,但是如果源字节太大,我更喜欢使用“窗口”函数来按块处理字节块。 否则它将占用大量内存。

我拼凑的东西……很快就要测试了。 从如何将字节数组转换为hex字符串,反之亦然?

  public byte[] ReplaceBytes(byte[] src, string replace, string replacewith) { string hex = BitConverter.ToString(src); hex = hex.Replace("-", ""); hex = hex.Replace(replace, replacewith); int NumberChars = hex.Length; byte[] bytes = new byte[NumberChars / 2]; for (int i = 0; i < NumberChars; i += 2) bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16); return bytes; } 

不幸的是,所有post都存在问题(正如评论中已经指出的那样)。 在另一个问题中有一个正确的答案

我需要一个解决方案,所以我自己写了下面的代码。 这在使用可枚举和多个搜索替换术语时也更灵活。

 using System; using System.Collections.Generic; using System.Linq; using System.Text; public class ByteTools { static void ByteReplaceTests() { var examples = new(string source, string search, string replace)[] { ("bababanana", "babanana", "apple"), ("hello guys", "hello", "hello world"), ("apple", "peach", "pear"), ("aaaa", "a", "abc"), ("pear", "pear", ""), ("good morning world", "morning", "morning"), ("ababab", "ab", "ababab"), ("ababab", "abab", "ab"), ("", "aa", "bb"), }; int i = 0; foreach (var (source, search, replace) in examples) { var stringReplaceResults = source.Replace(search, replace); var sourceByte = Encoding.ASCII.GetBytes(source); var searchByte = Encoding.ASCII.GetBytes(search); var replaceByte = Encoding.ASCII.GetBytes(replace); //converts string values to bytes, does the replace, then converts back to string var byteReplaceResults = Encoding.ASCII.GetString( ByteReplace(sourceByte, (searchByte, replaceByte)).ToArray()); Console.WriteLine($"{i}: {source}, {search}, {replace}"); Console.WriteLine($" String.Replace() => {stringReplaceResults}"); Console.WriteLine($" BytesReplace() => {byteReplaceResults}"); i++; } } static IEnumerable ByteReplace(IEnumerable source, params (byte[] search, byte[] replace)[] replacements) { if (source == null) throw new ArgumentNullException(nameof(source)); if (replacements == null) throw new ArgumentNullException(nameof(replacements)); if (replacements.Any(r => r.search == null || r.search.Length == 0)) throw new ArgumentOutOfRangeException(nameof(replacements), "Search parameter cannot be null or empty"); if (replacements.Any(r => r.replace == null)) throw new ArgumentOutOfRangeException(nameof(replacements), "Replace parameter cannot be null"); var maxMatchSize = replacements.Select(r => r.search.Length).Max(); var bufferSize = maxMatchSize * 2; var buffer = new byte[bufferSize]; int bufferStart = 0; int bufferPosition = 0; byte[] nextBytes() { foreach ((byte[] search, byte[] replace) in replacements) { if (ByteStartsWith(buffer, bufferStart, bufferPosition - bufferStart, search)) { bufferStart += search.Length; return replace; } } var returnBytes = new byte[] { buffer[bufferStart] }; bufferStart++; return returnBytes; } foreach (var dataByte in source) { buffer[bufferPosition] = dataByte; bufferPosition++; if (bufferPosition - bufferStart >= maxMatchSize) { foreach (var resultByte in nextBytes()) yield return resultByte; } if (bufferPosition == bufferSize - 1) { Buffer.BlockCopy(buffer, bufferStart, buffer, 0, bufferPosition - bufferStart); bufferPosition -= bufferStart; bufferStart = 0; } } while (bufferStart < bufferPosition) { foreach (var resultByte in nextBytes()) yield return resultByte; } } static bool ByteStartsWith(byte[] data, int dataOffset, int dataLength, byte[] startsWith) { if (data == null) throw new ArgumentNullException(nameof(data)); if (startsWith == null) throw new ArgumentNullException(nameof(startsWith)); if (dataLength < startsWith.Length) return false; for (int i = 0; i < startsWith.Length; i++) { if (data[i + dataOffset] != startsWith[i]) return false; } return true; } }