1

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?

7
  • let's suppose I have this pattern: 010101 and I want to change it with X Commented Jul 23, 2016 at 14:45
  • Yes, would be great! Commented Jul 23, 2016 at 14:46
  • E.g I start reading and creating chunks of 10 bits, then if this pattern is in these chunks replace with X Commented Jul 23, 2016 at 14:48
  • A couple of questions - is X the same length as the pattern? And how big is the array? (ie do we need to be efficient?) Commented Jul 23, 2016 at 14:49
  • The array might be very big (but it won't happen very often) I would say the size will be around 50 Mb / file... X yeah Commented Jul 23, 2016 at 14:52

2 Answers 2

0

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);
Sign up to request clarification or add additional context in comments.

1 Comment

@DavidE sorry I don't understand what you are asking. I didn't write for using a replace method. Set method have 2 inputs, the first one is the index in the bit array. So if he wants to change the 10th bit to 1, he has to write bits.Set(9, true);
0

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

1 Comment

@Ben You make a BitArray from a byte[], no? So do you not need: BitArray value = new BitArray(new [] {xh}) ?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.