Reputation: 3
Basically I'm trying to recreate a program where I input an info (1 to 8 bytes) to get an output info (1 to 7 bytes), I know that's happening some bit-manipulation, but I can't find a definitive pattern to create the Algorithm.
Below some methods that I created for the bit-manipulation:
public byte ChangeMSB(byte input)
{
byte[] output = { 0x00 };
var bits = new BitArray(new byte[] { input });
bits.Set(bits.Length - 1, true);
bits.CopyTo(output, 0);
return output[0];
}
public byte RightShiftBits(byte input, int count)
{
byte[] output = { 0x00 };
var bits = new BitArray(new byte[] { input });
bits.RightShift(count);
bits.CopyTo(output, 0);
return output[0];
}
public byte LeftShiftBits(byte input, int count)
{
byte[] output = { 0x00 };
var bits = new BitArray(new byte[] { input });
bits.LeftShift(count);
bits.CopyTo(output, 0);
return output[0];
}
public byte OrBits(byte firstByte, byte secondByte)
{
byte[] ORed = { 0x00 };
var firstBits = new BitArray(new byte[] { firstByte });
var secondBits = new BitArray(new byte[] { secondByte });
var ORedBits = firstBits.Or(secondBits);
ORedBits.CopyTo(ORed, 0);
return ORed[0];
}
Then I tried to create an algorithm, but it doesn't work on every situation:
public byte[] Try(byte[] input)
{
byte[] output;
switch (input.Length)
{
case 1:
return input;
case 8:
output = new byte[input.Length - 1];
break;
default:
output = new byte[input.Length];
break;
}
Array.Copy(input, output, output.Length);
for (int i = 0; i < output.Length; i++)
{
if (i != output.Length - 1)
{
output[i] = ChangeMSB(output[i]);
}
output[i] = RightShiftBits(output[i], i);
if (i + 1 != output.Length && !input[i].Equals(input[i + 1]))
{
output[i] = ChangeMSB(output[i]);
}
if (i == 6 && input.Length == 8)
{
output[i] = OrBits(output[i], LeftShiftBits(input[input.Length - 1], 1));
break;
}
}
return output;
}
public byte[] Try2(byte[] input)
{
byte[] output;
switch (input.Length)
{
case 1:
return input;
case 8:
output = new byte[input.Length - 1];
break;
default:
output = new byte[input.Length];
break;
}
Array.Copy(input, output, output.Length);
for (int i = 0; i < output.Length; i++)
{
int operation = 0;
for (int j = i; j > 0; j--)
{
if (i > 0)
{
operation = (int)output[i] / 2;
output[i] = (byte)operation;
}
if (IsOdd(output[i]) && i != output.Length - 1)
{
output[i] = ChangeMSB(output[i]);
}
}
output[0] = ChangeMSB(output[0]);
if (i == 6 && input.Length == 8)
{
operation = (int)output[i] + input[input.Length - 1] * 2;
output[i] = (byte)operation;
break;
}
}
return output;
}
I only found 2 patterns:
k
output[6] = OrBits(RightShiftBits(input[6], 6), LeftShiftBits(input[7], 1)) or (int)input[6]/2^6 + (int)input[7]*2;
Below some tests with the original Program with hex values: Encoding: GSM 7-bit Default Alphabet
input = 41 (A) | output = 41;
input = 41 41 (AA) | output = C1 20;
input = 41 41 41 (AAA) | output = C1 60 10;
input = 41 42 43 44 45 46 47 (ABCDEFG) | output = 41 E1 90 58 34 1E 01;
input = 41 42 43 44 45 46 47 48 (ABCDEFGH) | output = 41 E1 90 58 34 1E 91;
input = 48 47 46 45 44 43 42 41 (HGFEDCBA) | output = C8 A3 B1 48 1C 0A 83;
input = 4D 43 4B (MCK) | output = CD E1 12;
These are my outputs using the same inputs:
output = 41;
output = C1 20;
output = C1 60 10;
output = C1 E1 B0 98 8C 86 01;
output = C1 E1 B0 98 8C 86 91;
output = C8 E3 B1 98 8C 86 83;
output = CD E1 12;
Upvotes: 0
Views: 72
Reputation: 2973
Your input is a string of 7-bit values, and your output is what you obtain when you put the 7-bit values together and read off 8 bits at a time.
An easy way to obtain this encoding is by putting the 7-bit values into a single "long" variable (which holds up to 64 bits) using left shifts. Then you can read off 8 bits at a time using right shifts.
byte[] input = {0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47};
long x = 0;
for (int i = 0; i < input.Length; i += 1) x |= ((long)input[i]) << (7 * i);
byte[] output = new byte[(input.Length * 7 + 7) / 8];
for (int i = 0; i < output.Length; i += 1) output[i] = (byte)(x >> (8 * i));
for (int i = 0; i < output.Length; i += 1) Console.Write("{0:X} ", output[i]);
Prints: 41 E1 90 58 34 1E 1
Upvotes: 1