Use PHP to Decode BASE64 encoded Signed Integers in 16bit - c#
I have a Base64 encoded string and I am using the following c# code to decode it. Inside should be a range of Signed integers stored in 16bit.
Now I need to do it in PHP but I'm having real trouble. Can anyone help?
Basically can anyone convert this code to php?
private string decode(string encoded)
{
Byte[] newBytes = Convert.FromBase64String(
encoded.Replace("\n","")
);
int[] newArr = new int[newBytes.Length / 4];
for (int ctr = 0; ctr < newBytes.Length / 4; ctr++)
newArr[ctr] = BitConverter.ToInt16(newBytes, ctr * 4);
return DisplayArray(newArr);
}
private string DisplayArray(Array arr)
{
string output = "";
for (int ctr = 0; ctr < arr.GetUpperBound(0); ctr++)
{
output += arr.GetValue(ctr) + ",";
}
return output;
}
Here is the base64 string....
AgACAAAAAgAAAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAUABQAFAAUABQAF
AAUAAgACAAAA/v8AAAIABwAHAAUABQAFAAUAAAAAAAAAAgAAAAAAAgACAAUA
BQAFAAIAAgAFAAIAAAAAAAAAAAACAAAAAAACAAIAAAAAAAIABQAFAAUAAgAC
AAIAAgACAAIAAgACAAUAAgACAAIAAgACAAUABQAFAAIAAAAAAAUA/v8CAAIA
AgACAAAAAgAFAAUABQAFAAAAAgACAAIAAAACAAIABQACAAIABQAFAAcAAgAF
AAUAAgAAAAAAAgACAAUAAgACAAIAAAACAAUABQACAAUABQACAAIAAAACAAIA
AgACAAUABQAFAAAA/v/+/wAAAgACAAIAAAAAAAIAAgAAAAAAAgAFAAUABQAC
AAAAAAACAAIAAgACAAIAAAAAAAIAAAACAAIAAgACAAUAAgAFAAUABQACAAUA
BQAFAAcABQAFAAUABQAFAAUABQAHAAcABwAFAAUABwAHAAUABwAHAAUABwAH
AAUABwAHAAcABQAFAAUAAgAAAP7/AAACAAIAAgACAAUABQAFAAUAAgAFAAIA
BQACAAUABwAFAAIABQAFAAIABQACAAAABwAHAAUAAgAFAAUAAgAAAAAAAgAF
AAIABQAHAAcABQACAAIAAgACAAIAAgAFAAcABQAHAAcABwAHAAcABQAFAAUA
AgACAAUABQAFAAUABQAHAAoACgAKAAoABwAHAAoACgAKAAcACgAKAAwADAAM
AAwADAAPABEAEQAPAA8AFAARABQAFAAUABQAFgAWABEAEQAUABQAFAAWABYA
FgAZABsAGwAbABsAGwAbACAAIAAgACMAJQAoACUAKAAoACgAKAAoACgAKAAl
ACUAJQAlACUAJQAlACgAKgAqACgAJQAjACMAIAAeACAAIwAgABkAGQAZABkA
FAARAA8ADAAKAAcABwAFAAIABQAHAAcABQACAAIAAgACAAIAAAAAAAAA/v/+
/wAAAAAAAAIAAAD+//7/AAACAAUAAgACAAIAAAACAAUAAAAAAAAAAAAAAAAA
/v/+//7/AAAAAP7//v8AAAAA/v/+//7/+//7//v//v8AAAAA/v/7//7//v8A
AP7//v/7//7//v8AAP7/AAAAAAAAAAACAAIAAAAAAAAAAAAAAAIABQAHAAUA
BwAKAAoADwAUABsAIwAqAC8AOQBBAE0AWgBhAGkAcwB/AI4AmwClALEAuwDF
ANIA3gDrAPUABgEaASkBOAFKAV4BdAGGAZIBnwGuAb8BxwHRAdsB6gH2AQAC
BQIAAvkB6gHdAccBrgGVAYMBbQFUATgBGAH1ANwA1wDPAMoAyADAALQApwCb
AJMAiQCCAH0AcwBrAGYAXwBaAFIASwBGAEEAOQAvACUAHgAWABQAEQAMAAwA
DAAMAAwABwAFAAUAAgACAAAA/v8AAAAAAAD+//7/+//7//n/+f/2//b/+f/7
//n/+f/5//n/+//2//T/+//5//n/9v/5//n/9v/2//T/9v/0//n/+f/5//b/
9v/2//n/9v/2//T/9v/5//b/+f/5//n/+f/5//b/9P/2//T/7//x//T/9P/0
//b/9v/0//b/9P/2//b/9v/2//b/9P/x//H/8f/v//H/9P/x//T/9P/0//H/
8f/0//H/8f/x//H/8f/0//H/8f/x//H/8f/s/+z/7//v//H/8f/s/+z/7P/s
/+z/7P/s/+r/6v/s/+r/5//s/+r/6v/q/+r/6v/q/+f/5//n/+X/5f/n/+r/
6v/s/+f/5//l/+f/5//l/+L/5f/l/+X/5//i/+L/4v/i/+X/5f/i/+L/4P/d
/93/4v/i/+L/4v/g/93/3f/g/+D/3f/d/93/3f/b/93/2//b/9j/3f/b/9v/
2P/W/9j/1v/W/9P/0//R/9H/0//R/9b/1v/T/9H/0f/O/9P/0f/O/8z/zv/O
/87/zP/M/87/zP/M/8n/x//H/8f/zP/M/8z/yf/J/8z/zP/O/8z/yf/H/8T/
xP/H/8f/yf/J/8n/zP/M/8n/x//H/8n/yf/M/8z/zP/O/8z/zP/M/87/zv/R
/9H/0f/T/9P/0f/R/9P/1v/W/9j/3f/d/+D/4P/d/93/4v/i/+X/5//n/+z/
7//v/+//9P/2//b/9P/2//v/+//+/wAAAAACAAIABQAKAAoADAAMAAwACgAK
AAwADAAMAAwADAAMAA8AEQARABEAEQARABEADwARABQAFAARABEADwARABQA
EQARABEAEQAUABEAFAAUAA8AEQARAAwAEQARABEADwAPAAwADwARABEAEQAM
AAwACgAKAAoACgAKAAoACgAMAAwADAAKAAcACgAKAAwACgAFAAUACgAKAAoA
CgAKAAUABwAHAAcACgAHAAcABQAHAAUABwAKAAoABQACAAUABwAHAAcABQAC
AAIABQAFAAIAAgAFAAUACgAFAAUABwAHAAUABQAFAAIAAgACAAAAAgAFAAUA
BQAFAAcABwAFAAUABQAFAAcABwAHAAcABQAFAAUABQAFAAUABQAFAAUABQAH
AAcABQAFAAUABQAFAAIAAgACAAUABwAFAAUAAgACAAUABQAFAAUABQAKAAoA
BQAFAAcABwAFAAUABwACAAIAAgAHAAcABQAFAAUABQACAAAAAAAAAAIAAgAC
AAAAAAD+/wAAAAACAAIABQAFAAUABQACAAIAAgAAAAIAAgACAAAAAAACAAIA
AgAAAP7/AAACAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAA
AAIAAgAAAAIAAAAAAAAAAAAAAAAAAgACAAAAAAACAAAAAAACAAAAAAACAAIA
AgACAAIAAgACAAIAAAAAAAAAAgACAAIAAgACAAIA/v8AAAIAAgACAAIABQAF
AAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIA
AgACAAIAAgACAAIAAgACAAUAAgACAAIAAgACAAIAAgACAAIAAgAFAAUAAgAA
AAAAAgACAAIAAgACAAIAAgACAAIAAgAFAAUAAgACAAIABQAFAAIAAgACAAAA
AgAFAAUABwAFAAIAAAACAAAA/v/7//7/AAAAAAIABwAHAAUAAgAAAAIABwAF
AAIAAgACAAIAAgACAAIA
and it should decode to...
2,0,0,2,2,2,2,2,2,5,5,5,2,0,0,7,5,5,0,0,0,2,5,5,2,2,0,0,0,2,0,2,5,2,2,2,2,5,2,2,5,5,0,5,2,2,0,5,5,0,2,0,2,2,5,7,5,2,0,2,2,2,2,5,5,2,0,2,2,5,0,-2,2,2,0,2,0,5,5,0,2,2,2,0,0,2,2,2,5,2,5,7,5,5,5,7,7,5,7,7,5,7,7,7,5,2,-2,2,2,5,5,2,2,2,7,2,5,5,0,7,2,5,0,2,2,7,5,2,2,2,7,7,7,7,5,2,5,5,5,10,10,7,10,10,10,12,12,12,17,15,20,20,20,22,17,20,20,22,25,27,27,27,32,35,40,40,40,40,40,37,37,37,40,42,37,35,30,35,25,25,20,15,10,7,2,7,5,2,2,0,0,-2,0,2,-2,0,5,2,0,5,0,0,0,-2,0,-2,0,-2,-2,-5,-2,0,-5,-2,-2, etc...
The good
PHP makes it really easy to read in base64 data and convert it to an array of signed integers. Make sure to read up on the unpack function, it's great.
$stringValue = base64_decode($base64data, true);
$integers = unpack("s*", $stringValue);
The bad
That is not what your C# code is doing. After converting the base64 into raw bytes, it then processes that data in chunks of 4 bytes, parsing the first 2 into an int16 and throwing away the second two bytes. Half your data goes down the drain.
The ugly
If the C# code is really the algorithm you are after, here is how to do it in PHP:
$stringValue = base64_decode($base64data, true);
$integers = unpack("s*", $stringValue);
// Throw away half of our data. Because... why not? :)
$integers = array_map('array_shift', array_chunk($integers, 2));
Related
PHP - C# translated hashing function not working?
I'll get right to the question, We have this block of C# code using (Rfc2898DeriveBytes pbkdf2 = new Rfc2898DeriveBytes(password, passwordSaltBytes, iterationCount)) { pbkdf2Bytes = pbkdf2.GetBytes(derivedLength + iterationCountBytes.Length); } Returns a byte array, first index has a value of 252 We attempt the same thing in PHP: $key = hash_pbkdf2("SHA1", $password, $password.$salt, $iterationCount, 48); First index is 102... The values all match before this specific part. It's just that hashing function that isn't giving me consistent results. Any help is appreciated, cheers. Edit - If it's not obvious, I'm trying to understand why those two values don't match, what encoding/decoding etc. am I misunderstanding or doing incorrectly.
This is the full C# code. As you can see there are some unnecessary loops etc. but the reasons why this wasn't working are 2: As somebody pointed out, the bytes in PHP do no output raw data by default, and thus the hash (and consequently as such,) its bytes, weren't identical with that of the C# script. Previously, I thought (as others also pointed out) that I should pass in the $salt as it is without any encoding or transformation. But upon looking closer at the actual C# code... we can see in the 2nd for i loop that they're actually appending saltBytes onto passwordBytes, thus creating something similar to $password.$salt in PHP Combining the two above issues: Sending the $password.$salt instead of just one, and then setting the $raw_output option to true, outputs the same hash, the same bytes as C# does. byte[] passwordBytes = Encoding.UTF8.GetBytes(password); byte[] saltBytes = Encoding.UTF8.GetBytes(salt); byte[] iterationCountBytes = BitConverter.GetBytes(iterationCount); int derivedLength = passwordBytes.Length + saltBytes.Length; byte[] passwordSaltBytes = new byte[derivedLength]; byte[] pbkdf2Bytes; string encryptedString; for (int i = 0; i < passwordBytes.Length; i++) { passwordSaltBytes[i] = passwordBytes[i]; } for (int i = 0; i < saltBytes.Length; i++) { passwordSaltBytes[passwordBytes.Length + i] = saltBytes[i]; } using (Rfc2898DeriveBytes pbkdf2 = new Rfc2898DeriveBytes(password, passwordSaltBytes, iterationCount)) { pbkdf2Bytes = pbkdf2.GetBytes(derivedLength + iterationCountBytes.Length); } Thanks.
Byte to value error
So in c#, I have needed a random below given number generator and I found one on StackOverFlow. But near the end, it converts the byte array into a BigInteger. I tried doing the same, though I am using the Deveel-Math lib as it allows me to us BigDeciamals. But I have tried to the array change into a value, and that into a String but I keep getting a "Could not find any recognizable digits." error and as of now I am stumped. public static BigInteger RandomIntegerBelow1(BigInteger N) { byte[] bytes = N.ToByteArray(); BigInteger R; Random random = new Random(); do { random.NextBytes(bytes); bytes[bytes.Length - 1] &= (byte)0x7F; //force sign bit to positive R = BigInteger.Parse(BytesToStringConverted(bytes)) ; //the Param needs a String value, exp: BigInteger.Parse("100") } while (R >= N); return R; } static string BytesToStringConverted(byte[] bytes) { using (var stream = new MemoryStream(bytes)) { using (var streamReader = new StreamReader(stream)) { return streamReader.ReadToEnd(); } } } Deveel-Math
Wrong string conversion You are converting your byte array to a string of characters based on UTF encoding. I'm pretty sure this is not what you want. If you want to convert a byte array to a string that contains a number expressed in decimal, try this answer using BitConverter. if (BitConverter.IsLittleEndian) Array.Reverse(array); //need the bytes in the reverse order int value = BitConverter.ToInt32(array, 0); This is way easier On the other hand, I notice that Deveel-Math's BigInteger has a constructor that takes a byte array as input (see line 226). So you should be able to greatly simplify your code by doing this: R = new Deveel.Math.BigInteger(1, bytes) ; However, since Deveel.Math appears to be BigEndian, you may need to reverse the array first: System.Array.Reverse(bytes); R = new Deveel.Math.BigInteger(1, bytes);
How can I convert a Base64 string to a float array or int array?
I have some code that converts a float[] to a Base64 string: float[] f_elements = <from elsewhere in my code>; byte[] f_vfeat = f_elements.SelectMany(value => BitConverter.GetBytes(value)).ToArray(); string f_sig = Convert.ToBase64String(f_vfeat); I also have - basically - the same code that converts an int[] to a Base64 string: int[] i_elements = <from elsewhere in my code>; byte[] i_feat = i_elements.SelectMany(value => BitConverter.GetBytes(value)).ToArray(); string i_sig = Convert.ToBase64String(i_feat); Both of these produce Base64 strings as expected. However, now I need to decode back to an array, and I'm running into trouble. How can I go from my Base64 string(s), and get the original data array(s). Before I decode the Base64 string, I will know if it is suppose to be an int[] or float[], so I think that will help. Does anyone know how to do go from Base64 string to float[] or int[]?
You can use BitConverter.ToInt32 or BitConverter.ToSingle to convert part of an array: byte[] bytes = Convert.FromBase64String(); int[] ints = new int[bytes.Length / 4]; for (int i = 0; i < ints.Length; i++) { ints[i] = BitConverter.ToInt32(bytes, i * 4); } (And the equivalent for ToSingle, of course.) In my view, it's a shame that GetBytes doesn't have an overload to write the bytes directly into an existing array, instead of creating a new array on each call...
Is there something wrong with Convert.FromBase64String? byte[] i_feat = Convert.FromBase64String(i_sig)
C# Array.Value differs from created array in c++
What is the best way to handle the following situation in C#? I have a server application written in C/C++. For example It creates a unsigned char buffer with length 256. In this buffer the server stores the data the client sends to it. After storing, there are some cryptography checks with the received buffer. I'm writing a client for this server in C#. The problem is the buffer the server is expecting at fixed length of 256. When I create a byte[] array with content and total length of 256 the cryptography checks are failing. The reason I found out is simple. The server expects a buffer of 256 bytes long. For example if the message is "Hello World", the rest of the buffer has to be 0-padded. Or, better explained: the bytes need to be (unsigned) "204" or (signed) "-52". I think this is a C/C++ concept issue/problem. To solve my problem, I am setting that value explicitly. public static byte[] GetCBuffer(this byte[] data, int len) { byte[] tmp = new byte[len]; for(int i = 0; i < len; i++) if(i < data.Length) tmp[i] = data[i]; else tmp[i] = 204; return tmp; } Are there better ways to work with these art expected bytes? Am I not seeing something essential?
If you don't like if in your code, you can try LINQ: public static byte[] GetCBuffer(this byte[] data, int len) { byte[] tmp = Enumerable.Repeat((byte)204, len).ToArray(); for(int i = 0; i < data.Length; i++) { tmp[i] = data[i]; } return ret; } But conceptually, it's the same, just looks (arguably) a bit nicer.
Can you 'memset' the entire array to the desired fill character and then insert the actual data?
Is there any difference in calculating CRC32 checksum in C# and Java?
I have to calculate CRC32 checksum for a string in C# and send it to an external application. On the other end they will calculate it using Java. But my checksum does not match on the their end. e.g. CRC32 checksum of the following string 43HLV109520DAP10072la19z6 is 1269993351 on their end. And 2947932745 at my end using C# Please tell me what's going wrong in my code. I am using this 0xffffffff default seed and following crc table readonly static uint[] CRCTable = new uint[] { 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D };
CRC32 is calculated over a sequence of bytes and not over a string. So to calculate CRC32 you need to transform the string into bytes first. If you use a different encoding to transform a string to a sequence of bytes the result will be different. Thus you need to use the same encoding on both sides. I recommend using UTF-8 without BOM.
I have calculated CRC32 with Java and got the same you got in C#. I.e. CRC32(43HLV109520DAP10072la19z6)=2947932745. This means that either they have a bug in java, or you have a bug during transmission. Code follows. I suggest you try to send simple data to java application, like zeros or ones, and try to deduce how do they compute CRC. public static void main(String[] args) { CRC32 crc32 = new CRC32(); String data = "43HLV109520DAP10072la19z6"; String[] cs = new String[] {"utf8" /*, "cp1252", "cp866" */}; byte[] array; byte b; for(int i=0; i<cs.length; ++i) { array = data.getBytes(Charset.forName(cs[i])); crc32.reset(); crc32.update(array); System.out.println(String.format("%s: %d", cs[i], crc32.getValue())); /* for(int j=0; j<array.length/2; j++) { b = array[i]; array[i] = array[array.length-1-i]; array[array.length-1-i] = b; } */ for(int j=0; j<array.length; j+=2) { b = array[i]; array[i] = array[i+2]; array[i+1] = b; } crc32.reset(); crc32.update(array); System.out.println(String.format("of modified: %d", crc32.getValue())); } } UPDATE Endiannes reverse also not help for(int j=0; j<array.length; j+=4) { b = array[i]; array[i] = array[i+3]; array[i+3] = b; b = array[i+1]; array[i+1] = array[i+2]; array[i+2] = b; }
Without delving into any detail, the problem can be related to Java's lack of unsigned integer types. The problem could happen at the int level, but also at the byte level. This is one avenue of investigation.
CRC is calculated over a sequence of bytes and not over a string. Whichever CRC in java looks different due unavailability of Unsigned int in java. Convert calculated Int CRC into Hex String and take last 2 Bytes (length 4) That is your actual CRC unsigned Int. String hexCrc = Integer.toHexString(crcCalculated); hexCrc = hexCrc.substring(hexCrc.length()-4); compare hex CRC of c# and Java both should be same.