2

While running a program in my server (a beacon detection code), I will receive a variable size string, named io385.

The string length can vary according to how many beacons are detected:

  • One beacon: 46 bytes (first 4 bytes are useless, next 40 are important, next 2 are useless);
  • Two beacons: 90 bytes (first 2 bytes are useless, next 40 are important, next 2 are useless);
  • Three beacons: 134 bytes (first 2 bytes are useless, next 40 are important, next 2 are useless;

...

So, with this, my idea is to remove whatever is useless. Even though the string can vary in size, I always want to remove bytes on fixed positions (for the first beacon, first four and last 2; for the next beacons, first two and last two).

I started to manually remove the useless bytes on a 2 beacon string. However, I wanted to optimize this in order to automatically work whether the string is 46 bytes or xxxx bytes (otherwise, I'll have to manually code the character removal process for each possible string length).

        string io385 = "11210000AAAA0000AAAA0000AAAA0000AAAA0A0A0A0ABF210000BBBB0000BBBB0000BBBB0000BBBB0B0B0B0BBF";
        string informacao = String.Copy(io385);
        
        informacao = informacao.Remove(0,4).Remove(40,2).Remove(40,2).Remove(80,2);
        
        
        int x = io385.Length;
        int y = informacao.Length;
        Console.WriteLine("Original String: {0}", io385); 
        Console.WriteLine("Copied String: {0}", informacao);
        Console.WriteLine("Original String length: {0}", x);
        Console.WriteLine("Copied String length: {0}", y);
Jonaas18
  • 33
  • 5
  • 3
    You say you want to remove "bytes", but are you really referring to characters? Different character sets have a different numbers of bytes per character. – Rufus L Sep 09 '20 at 22:19
  • 1
    Does this question actually have anything to do with `teltonika`? It sounds like it's only about removing characters from a string. – Rufus L Sep 09 '20 at 22:22
  • Iterator method, if(length = 46) substring else for loop i+=44 substring yield – TheGeneral Sep 09 '20 at 22:41
  • @RufusL My bad, yes I mean characters, not bytes. Also, yes, all equipments are manufactured by teltonika, added the tag since it could be useful to other people! – Jonaas18 Sep 10 '20 at 01:12
  • @MichaelRandall I'm new to C# (only coded in C / C++) but I understand your idea! I'll try to create a solution based around that and edit the post as soon as I'm done! – Jonaas18 Sep 10 '20 at 01:14

2 Answers2

3

Given

public static IEnumerable<string> GetStuff(string input)
{
    Console.WriteLine(input.Length);
    if (input.Length == 46)
        yield return input.Substring(4, 40);
    else
        for (var i = 0; i < input.Length; i += 44)
            yield return input.Substring(i + 2, 40);
}

Usage

var input = "xxxx1234567890123456789012345678901234567890xx";
var input2 = "xx1234567890123456789012345678901234567890xxxx1234567890123456789012345678901234567890xxxx1234567890123456789012345678901234567890xxxx1234567890123456789012345678901234567890xx";
Console.WriteLine(string.Join("\r\n", GetStuff(input)));
Console.WriteLine();
Console.WriteLine(string.Join("\r\n", GetStuff(input2)));

Output

46
1234567890123456789012345678901234567890

176
1234567890123456789012345678901234567890
1234567890123456789012345678901234567890
1234567890123456789012345678901234567890
1234567890123456789012345678901234567890

Full Demo Here

TheGeneral
  • 79,002
  • 9
  • 103
  • 141
0

One way to do this is to first remove the first two characters so that all the "beacons" are the same length (44 characters) in the string. Now we can create a loop in which we go from 0 to length / 44, where we skip iteration * 44 characters (i.e. skip previous beacons), then skip 2 more characters (i.e. the leading 2 for this beacon) and then take 40 characters (the number of characters we care about).

In a method this might look something like this:

public static string RemoveUselessCharacters(string input)
{
    // Add argument validation first
    if (string.IsNullOrWhiteSpace(input) || input.Length < 46) return input;

    // Just remove the first two characters right away
    input = input.Substring(2);

    // This will hold the result
    var result = new StringBuilder();

    // Loop once for every beacon
    for (int i = 0; i < input.Length / 44; i++)
    {
         // Skip previous beacons plus two characters, then take 40 characters
        result.Append(string.Concat(input.Skip(i * 44 + 2).Take(40)));
    }

    // Return just the beacon charcters for all the beacons
    return result.ToString();
}

If you wanted to modify the code to return a List<string>, where each string was a separate beacon, it is easily done:

public static List<string> GetBeacons(string input)
{
    if (string.IsNullOrWhiteSpace(input) || input.Length < 46) 
        return new List<string> {input};

    input = input.Substring(2);
    var result = new List<string>();

    for (int i = 0; i < input.Length / 44; i++)
    {
        result.Add(string.Concat(input.Skip(i * 44 + 2).Take(40)));
    }

    return result;
}
Rufus L
  • 36,127
  • 5
  • 30
  • 43