Ben
Ben

Reputation: 304

Replace bit in BitArray c#

I am using this to convert a file into a BitArray:

public static byte[] GetBinaryFile(string filename)
{
    byte[] bytes;
    using (FileStream file = new FileStream(filename, FileMode.Open, FileAccess.Read))
    {
       bytes = new byte[file.Length];
       file.Read(bytes, 0, (int)file.Length);
    }
    return bytes;
}
var x=GetBinaryFile(@"path");
BitArray bits = new BitArray(x);

How do I replace a pattern of Bit in a BitArray?

Upvotes: 1

Views: 1150

Answers (2)

David E
David E

Reputation: 1444

The below code should work, using a basic two-pass algorithm to find match locations and then do the replacements.

Note that for 10MB files, it takes roughly 10 seconds on my semi-decent laptop. If you want it to go faster, you can implement it using byte arrays and masks instead of the clunky and not-so-powerful BitArray abstraction.

Even better, you could use unsafe code, where you can make use of pointers and much faster copying... But as it's a C# question and you're already using the BitArray abstraction, I thought I'd show you how it can be achieved as is.

    private static BitArray Replace(BitArray input, BitArray pattern, BitArray replacement)
    {
        var replacementPositions = GetReplacementPositions(input, pattern);
        return PerformReplacements(input, pattern.Length, replacement, replacementPositions);
    }

    private static List<int> GetReplacementPositions(BitArray input, BitArray pattern)
    {
        if (pattern.Length == 0) throw new Exception("Pattern cannot have 0 length");

        var matchIndicies = new List<int>();
        var maxCheckIndex = input.Length - pattern.Length;
        var i = 0;
        while (i <= maxCheckIndex)
        {
            if (MatchesAt(input, pattern, i))
            {
                matchIndicies.Add(i);
                i += pattern.Length;
                continue;
            }
            i++;
        }
        return matchIndicies;
    }

    private static bool MatchesAt(BitArray input, BitArray pattern, int index)
    {
        for (var j = 0; j < pattern.Length; j++)
        {
            if (input[index + j] != pattern[j]) return false;
        }
        return true;
    }

    private static BitArray PerformReplacements(BitArray input, int patternLength, BitArray replacement, List<int> replacementPositions)
    {
        var outLength = input.Length + replacementPositions.Count * (replacement.Length - patternLength);
        var output = new BitArray(outLength);

        var currentReadIndex = 0;
        var currentWriteIndex = 0;
        foreach (var matchPosition in replacementPositions)
        {
            var inputSubstringLength = matchPosition - currentReadIndex;

            CopyFromTo(input, output, currentReadIndex, inputSubstringLength, currentWriteIndex);

            currentReadIndex = matchPosition + patternLength;
            currentWriteIndex += inputSubstringLength;

            CopyFromTo(replacement, output, 0, replacement.Length, currentWriteIndex);
            currentWriteIndex += replacement.Length;
        }
        CopyFromTo(input, output, currentReadIndex, input.Length - currentReadIndex, currentWriteIndex);
        return output;
    }

    private static void CopyFromTo(BitArray from, BitArray to, int fromIndex, int fromLength, int toIndex)
    {
        for (var i = 0; i < fromLength; i++)
        {
            to.Set(toIndex + i, from.Get(fromIndex + i));
        }
    }

Upvotes: 0

Ashkan S
Ashkan S

Reputation: 11491

you can use Set method to set special bit in the BitArray.

bits.Set(index, value); 

value is a bool, which will translate to 0 and 1 in your bitarray

i.e: To set the 10th bit to 1 use

bits.Set(9, true);

Upvotes: 0

Related Questions