C # Replace bytes in bytes []

What is the best way to replace some bytes in a byte array?

For example, I have one bytesFromServer = listener.Receive(ref groupEP);, and I can do BitConverter.ToString(bytesFromServer)to convert it to a readable format, to return something along the lines

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   

I would like to replace something inside this “68 65 6c” with something like “68 00 00” (as an example). .Replace () does not exist in byte [].

Will there be an easy way to convert this back to byte []?

Any help appreciated. Thank!

+4
source share
6 answers

You could program it ... try this for a start ... this, however, is not reliable and not production like code ... beaware of-by-one errors I have not fully tested this ...

    public int FindBytes(byte[] src, byte[] find)
    {
        int index = -1;
        int matchIndex = 0;
        // handle the complete source array
        for(int i=0; i<src.Length; i++)
        {
            if(src[i] == find[matchIndex])
            {
                if (matchIndex==(find.Length-1))
                {
                    index = i - matchIndex;
                    break;
                }
                matchIndex++;
            }
            else if (src[i] == find[0])
            {
                matchIndex = 1;
            }
            else
            {
                matchIndex = 0;
            }

        }
        return index;
    }

    public byte[] ReplaceBytes(byte[] src, byte[] search, byte[] repl)
    {
        byte[] dst = null;
        int index = FindBytes(src, search);
        if (index>=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;
    }

Implementation as an extension method

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});
+10
+4

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

, , "" . .

+3

-, ... , . - ?

     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;
    }
0

Unfortunately, there are problems with all posts (as already mentioned in the comments). There is a correct answer to this question.

I needed a solution for myself and wrote the following code. It is also more flexible in using enumerable and multiple replacement conditions.

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<byte> ByteReplace(IEnumerable<byte> 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;
    }
}
0
source
    public static byte[] ReplaceBytes(byte[] src, byte[] search, byte[] repl)
    {
        if (repl == null) return src;
        int index = FindBytes(src, search);
        if (index < 0) return src;
        byte[] dst = new byte[src.Length - search.Length + repl.Length];
        Buffer.BlockCopy(src, 0, dst, 0, index);
        Buffer.BlockCopy(repl, 0, dst, index, repl.Length);
        Buffer.BlockCopy(src, index + search.Length, dst, index + repl.Length,src.Length - (index + search.Length));
        return dst;
    }

    public static int FindBytes(byte[] src, byte[] find)
    {
        if(src==null|| find==null|| src.Length==0|| find.Length == 0 || find.Length> src.Length) return -1;
        for (int i = 0; i < src.Length - find.Length +1 ; i++)
        {
            if (src[i] == find[0])
            {
               for(int m=1;m< find.Length;m++)
               {
                    if (src[i + m] != find[m]) break;
                    if (m == find.Length - 1) return i;
               }
            }
        }
        return -1;
    }

it can be a good method, I have a test for many codes.

-1
source

Source: https://habr.com/ru/post/1795037/


All Articles