Hello World !,
i tried to translate a piece of code to java but I have problems about the ranges of the datatypes and the bit operations is someone able to help.
Both Code pieces are ready to compile and work but get different results
If someone could help I would be really thankful !!!
The Go-Code :
package main
import (
"encoding/binary"
"fmt"
"strconv"
)
func crc32v(idx int) int {
POLY := 0x04c11db7
c := idx << 24 & 0xFFFFFFFF
for i := 0; i < 8; i++ {
k:= c&0x80000000
if k > 0 {
c = c<<1 ^ POLY
} else {
c = c << 1 & 0xFFFFFFFF
}
}
return c
}
func adler32(bs []byte) int {
s1 := 4
s2 := 0
for _, x := range bs {
s1 = (s1 + int(x)) % 65521
s2 = (s2 + s1) % 65521
}
res := (s2 << 16) | s1
return res
}
func prepareSubs(key []int) [][]int {
table1 := make([]int, 256)
for i := range table1 {
table1[i] = i
}
s := 0
for i := range table1 {
s += table1[i]
s += key[i%len(key)]
s &= 0xFF
table1[i] = table1[s]
}
table2 := make([]int, 256)
for i, v := range table1 {
table2[i] = v
}
s = 0
for i := range table2 {
if i > 0 {
s = (table2[i] + s) & 0xFF
table2[i] = table2[s]
}
}
out := [][]int{table1, table2}
return out
}
func Reverse(s string) (result string) {
for _, v := range s {
result = string(v) + result
}
return
}
func rbit(x int, width int) int {
x2 := strconv.FormatInt(int64(x), 2)
orig := len(x2)
for i := 0; i < width-orig; i++ {
x2 = fmt.Sprintf("0%s", x2)
}
x3, _ := strconv.ParseInt(Reverse(x2), 2, 32)
return int(x3)
}
func hashFunction(srcData []byte, timestamp int) string {
ldsBytes := []byte{0x0D, 0xC0, 0xA0, 0xE1, 0xF0, 0x00, 0x2D, 0xE9, 0xE9, 0x00, 0x40, 0xE2, 0x00, 0x70, 0xA0, 0xE1, 0x01, 0x00, 0xA0, 0xE1, 0x02, 0x10, 0xA0, 0xE1, 0x03, 0x20, 0xA0, 0xE1, 0x78, 0x00, 0x9C, 0xE8}
stackCrc := crc32v(0x63)
inpbs := make([]byte, 0)
for i := 0; i < 4; i++ {
next := srcData[i*16 : i*16+4]
for _, b := range next {
inpbs = append(inpbs, b)
}
}
// Append timestamp bytes to inpbs
tsBytes := make([]byte, 4)
binary.BigEndian.PutUint32(tsBytes, uint32(timestamp))
for _, b := range tsBytes {
inpbs = append(inpbs, b)
}
ldsChecksum := adler32(ldsBytes)
crcbs := 0
for i := 0; i < 4; i++ {
crcbs = (crcbs << 4) + (ldsChecksum & 0xff)
ldsChecksum >>= 8
}
crcbs = (crc32v(crcbs&0xFF) ^ crc32v((crcbs>>8)&0xFF))
key := []int{
crcbs & 0xFF,
0,
(crcbs >> 8) & 0xFF,
(stackCrc >> 8) & 0xFF,
(crcbs >> 16) & 0xFF,
(crcbs >> 24) & 0xFF,
0,
stackCrc & 0xFF,
}
// Returns multi-dimensional int array
sbox := prepareSubs(key)
result := make([]int, len(inpbs)) // It prepends like 6 bytes before the return
for r, i := range inpbs {
result[r] = int(i)
}
for i := range result {
result[i] ^= sbox[0][(sbox[1][i+1]<<1)&0xFF]
}
for i := range result {
x := ((result[i] << 4) & 0xF0) | ((result[i] >> 4) & 0xF)
x ^= result[(i+1)%len(result)]
x = rbit(x, 8)
x ^= 0xFF
x ^= 0x14
result[i] = x
}
pre := make([]int, len(result)+6)
pre[0] = 0x03
pre[1] = 0x6F
pre[2] = key[7]
pre[3] = key[3]
pre[4] = 0
pre[5] = 0
for r, v := range result {
pre[r+6] = v
}
str := ""
for _, p := range pre {
str = fmt.Sprintf("%s%02x", str, p)
}
fmt.Println("As []int: \t", pre)
fmt.Printf("As hex:\t\t%02x\n", pre)
fmt.Printf("As hex string:\t%v\n", str)
return str
}
func main() {
var favicon = []byte{
0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00,
0x10, 0x00, 0x00, 0x00, 0x0f, 0x04, 0x03, 0x00, 0x00, 0x00, 0x1f, 0x5d, 0x52, 0x1c, 0x00, 0x00, 0x00, 0x0f, 0x50,
0x4c, 0x54, 0x45, 0x7a, 0xdf, 0xfd, 0xfd, 0xff, 0xfc, 0x39, 0x4d, 0x52, 0x19, 0x16, 0x15, 0xc3, 0x8d, 0x76, 0xc7,
0x36, 0x2c, 0xf5, 0x00, 0x00, 0x00, 0x40, 0x49, 0x44, 0x41, 0x54, 0x08, 0xd7, 0x95, 0xc9, 0xd1, 0x0d, 0xc0, 0x20,
0x0c, 0x03, 0xd1, 0x23, 0x5d, 0xa0, 0x49, 0x17, 0x20, 0x4c, 0xc0, 0x10, 0xec, 0x3f, 0x53, 0x8d, 0xc2, 0x02, 0x9c,
0xfc, 0xf1, 0x24, 0xe3, 0x31, 0x54, 0x3a, 0xd1, 0x51, 0x96, 0x74, 0x1c, 0xcd, 0x18, 0xed, 0x9b, 0x9a, 0x11, 0x85,
0x24, 0xea, 0xda, 0xe0, 0x99, 0x14, 0xd6, 0x3a, 0x68, 0x6f, 0x41, 0xdd, 0xe2, 0x07, 0xdb, 0xb5, 0x05, 0xca, 0xdb,
0xb2, 0x9a, 0xdd, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82,
}
hashFunction(favicon,1)
}
The Java Code :
import java.nio.ByteBuffer;
import java.util.Arrays;
public class Lev {
public static long crc32v(long idx) {
int POLY = 0x04c11db7;
long c = (idx << 24) & 0xFFFFFFFF;
long k;
for (int i = 0; i < 8; i++) {
k = c&0x80000000;
if (k > 0) {
c = (c << 1) ^ POLY;
} else {
c = (c << 1) & 0xFFFFFFFF;
}
}
return c;
}
public static long adler32(int[] bs) {
long s1 = 4;
long s2 = 0;
for (int i = 0; i < bs.length; i++) {
s1 = (s1 + (int) bs[i]) % 65521;
s2 = (s2 + s1) % 65521;
}
long res = (s2 << 16) | s1;
return res;
}
public static long[][] prepareSubs(long[] key) {
long[] table1 = new long[256];
for (int i = 0; i < table1.length; i++) {
table1[i] = i;
}
int s = 0;
for (int i = 0; i < table1.length; i++) {
s += table1[i];
s += key[i % key.length];
s &= 0xFF;
table1[i] = table1[s];
}
long[] table2 = new long[256];
for (int i = 0; i < table1.length; i++) {
table2[i] = table1[i];
}
s = 0;
for (int i = 0; i < table2.length; i++) {
if (i > 0) {
s = (int) ((table2[i] + s) & 0xFF);
table2[i] = table2[s];
}
}
long[][] out = new long[][]{
table1, table2
};
return out;
}
// Reverse a string
static String Reverse(String s) {
StringBuilder sb = new StringBuilder(s);
return sb.reverse().toString();
}
public static int rbit(int x, int width) {
String x2 = Long.toString((long) x, 2);
int orig = x2.length();
for (int i = 0; i < width - orig; i++) {
x2 = String.format("0%s", x2);
}
int x3 = Integer.parseInt(Reverse(x2), 2);
return x3;
}
public static String hashFunction(int[] srcData, int timestamp) {
int[] ldsBytes = new int[]{
0x0D, 0xC0, 0xA0, 0xE1, 0xF0, 0x00, 0x2D, 0xE9, 0xE9, 0x00, 0x40, 0xE2, 0x00, 0x70, 0xA0, 0xE1, 0x01, 0x00, 0xA0, 0xE1, 0x02, 0x10, 0xA0, 0xE1, 0x03, 0x20, 0xA0, 0xE1, 0x78, 0x00, 0x9C, 0xE8
};
long stackCrc = crc32v(0x63);
byte[] inpbs = new byte[0];
for (int i = 0; i < 4; i++) {
int[] next = Arrays.copyOfRange(srcData, i * 16, i * 16 + 4);
for (int f = 0; f < next.length; f++) {
inpbs = append(inpbs, next[f]);
}
}
// Append timestamp bytes to inpbs
byte[] tsBytes = new byte[4];
tsBytes = ByteBuffer.allocate(4).putInt(timestamp).array();
//binary.BigEndian.PutUint32(tsBytes, uint32(timestamp))
for (int i = 0; i < tsBytes.length; i++) {
inpbs = append(inpbs, tsBytes[i]);
}
long ldsChecksum = adler32(ldsBytes);
long crcbs = 0;
for (int i = 0; i < 4; i++) {
crcbs = (crcbs << 4) + (ldsChecksum & 0xff);
ldsChecksum >>= 8;
}
crcbs = (crc32v(crcbs & 0xFF) ^ crc32v((crcbs >> 8) & 0xFF));
long[] key = new long[]{
crcbs & 0xFF,
0,
(crcbs >> 8) & 0xFF,
(stackCrc >> 8) & 0xFF,
(crcbs >> 16) & 0xFF,
(crcbs >> 24) & 0xFF,
0,
stackCrc & 0xFF,
};
// Returns multi-dimensional int array
long[][] sbox = prepareSubs(key);
int[] result = new int[inpbs.length]; // It prepends like 6 bytes before the return
for (int i = 0; i < inpbs.length; i++) {
result[i] = inpbs[i];
}
for(int i = 0; i < result.length;i++){
result[i] ^= sbox[0][(int) ((sbox[1][i + 1] << 1) & 0xFF)];
}
for(int i = 0; i < result.length;i++){
int x =((result[i] << 4) & 0xF0) | ((result[i] >> 4) & 0xF);
x ^= result[(i + 1) % result.length];
x = rbit(x, 8);
x ^= 0xFF;
x ^= 0x14;
result[i] = x;
}
long[] pre =new long[result.length + 6];
pre[0] = 0x03;
pre[1] = 0x6F;
pre[2] = key[7];
pre[3] = key[3];
pre[4] = 0;
pre[5] = 0;
for (int i = 0; i < result.length; i++) {
pre[i + 6] = result[i];
}
String str="";
for(int i = 0; i < pre.length; i++){
str = str.format("%s%02x", str, pre[i]);
}
System.out.println(str);
return str;
}
public static void main(String[] args) {
int[] favicon = new int[]{
0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00,
0x10, 0x00, 0x00, 0x00, 0x0f, 0x04, 0x03, 0x00, 0x00, 0x00, 0x1f, 0x5d, 0x52, 0x1c, 0x00, 0x00, 0x00, 0x0f, 0x50,
0x4c, 0x54, 0x45, 0x7a, 0xdf, 0xfd, 0xfd, 0xff, 0xfc, 0x39, 0x4d, 0x52, 0x19, 0x16, 0x15, 0xc3, 0x8d, 0x76, 0xc7,
0x36, 0x2c, 0xf5, 0x00, 0x00, 0x00, 0x40, 0x49, 0x44, 0x41, 0x54, 0x08, 0xd7, 0x95, 0xc9, 0xd1, 0x0d, 0xc0, 0x20,
0x0c, 0x03, 0xd1, 0x23, 0x5d, 0xa0, 0x49, 0x17, 0x20, 0x4c, 0xc0, 0x10, 0xec, 0x3f, 0x53, 0x8d, 0xc2, 0x02, 0x9c,
0xfc, 0xf1, 0x24, 0xe3, 0x31, 0x54, 0x3a, 0xd1, 0x51, 0x96, 0x74, 0x1c, 0xcd, 0x18, 0xed, 0x9b, 0x9a, 0x11, 0x85,
0x24, 0xea, 0xda, 0xe0, 0x99, 0x14, 0xd6, 0x3a, 0x68, 0x6f, 0x41, 0xdd, 0xe2, 0x07, 0xdb, 0xb5, 0x05, 0xca, 0xdb,
0xb2, 0x9a, 0xdd, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82,
};
hashFunction(favicon, 1);
}
public static byte[] append(byte[] arr, byte b){
byte[] re = new byte[arr.length+1];
for(int i = 0; i < arr.length; i ++){
re[i] = arr[i];
}
re[arr.length] = b;
return re;
}
public static byte[] append(byte[] arr, int b){
byte[] re = new byte[arr.length+1];
for(int i = 0; i < arr.length; i ++){
re[i] = arr[i];
}
re[arr.length] = (byte) b;
return re;
}
public static int[] append(int[] arr, byte b){
int[] re = new int[arr.length+1];
for(int i = 0; i < arr.length; i ++){
re[i] = arr[i];
}
re[arr.length] = b;
return re;
}
}