Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/347.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP中crc32b的输出不等于Python_Php_Python_Crc - Fatal编程技术网

PHP中crc32b的输出不等于Python

PHP中crc32b的输出不等于Python,php,python,crc,Php,Python,Crc,我正在尝试将PHP代码片段转换为Python3代码,但是print和echo的输出是不同的 您可以在步骤1中看到它 你知道问题出在哪里吗?我也附加了输入数组,但我认为它们是相等的 �W2+ vs ee7523b2 编辑 ------- 0 -> 1 1 100 EUR 20190101 11111111 Faktúra 1 SK6807200002891987426353 0 0 1 -> ee7523b2

我正在尝试将
PHP
代码片段转换为
Python3
代码,但是
print
echo
的输出是不同的

您可以在步骤1中看到它

你知道问题出在哪里吗?我也附加了输入数组,但我认为它们是相等的

�W2+ vs ee7523b2
编辑

-------
0 ->    1   1   100 EUR 20190101    11111111                Faktúra 1   SK6807200002891987426353        0   0
1 -> ee7523b2   1   1   100 EUR 20190101    11111111                Faktúra 1   SK6807200002891987426353        0   0
2 -> b'00006227515c7830302762275c783030325c7865305c7864386a34585c7862346d5c7838665c7865625c7863315c786266625c7839625c786339675c786332785c7831645c7862392c415c7862625c7831645c78663770365c786463735c786236572d606c225c7865355c7865635c7831345c7863655c786331205c7830635c7831315c7861375c7839345c7864665c7865635c7830365c7831652c22265c7866355c7862335c7866345c78616145585c7861625c7866395c7839615c7839645c7865645c7864625c7830305c7864355c7861643b5c7865365f5c7866645c786533405c78303027'
当我将raw从TRUE切换到FALSE时,第一步的输出是相同的<代码>$d=strev(散列(“crc32b”,“d,FALSE))$d

但问题是,我必须将PHP转换为Python,而不是相反,因为在第2步中,我需要使用相同的输出

PHP输出(CMD)

PYTHON输出

-------
0 ->    1   1   100 EUR 20190101    11111111                Faktúra 1   SK6807200002891987426353        0   0
1 -> ee7523b2   1   1   100 EUR 20190101    11111111                Faktúra 1   SK6807200002891987426353        0   0
2 -> b'00006227515c7830302762275c783030325c7865305c7864386a34585c7862346d5c7838665c7865625c7863315c786266625c7839625c786339675c786332785c7831645c7862392c415c7862625c7831645c78663770365c786463735c786236572d606c225c7865355c7865635c7831345c7863655c786331205c7830635c7831315c7861375c7839345c7864665c7865635c7830365c7831652c22265c7866355c7862335c7866345c78616145585c7861625c7866395c7839615c7839645c7865645c7864625c7830305c7864355c7861643b5c7865365f5c7866645c786533405c78303027'
PHP

<?php
$suma = "100";
$datum = "20190101";
$varsym = "11111111";
$konsym = "";
$specsym = "";
$poznamka = "Faktúra";
$iban = "SK6807200002891987426353";
$swift = "";

$d = implode("\t", array(
    0 => '',
    1 => '1',
    2 => implode("\t", array(
        true,
        $suma,                      // SUMA
        'EUR',                      // JEDNOTKA
        $datum,                 // DATUM
        $varsym,                    // VARIABILNY SYMBOL
        $konsym,                        // KONSTANTNY SYMBOL
        $specsym,                       // SPECIFICKY SYMBOL
        '',
        $poznamka,                  // POZNAMKA
        '1',
        $iban,  // IBAN
        $swift,                 // SWIFT
        '0',
        '0'
    ))
));
// 0
echo "0 -> ".$d."\n";
$d = strrev(hash("crc32b", $d, TRUE)) . $d;
// 1
echo "1 -> ".$d."\n";
$x = proc_open("/usr/bin/xz '--format=raw' '--lzma1=lc=3,lp=0,pb=2,dict=128KiB' '-c' '-'", [0 => ["pipe", "r"], 1 => ["pipe", "w"]], $p);
fwrite($p[0], $d);
fclose($p[0]);
$o = stream_get_contents($p[1]);
fclose($p[1]);
proc_close($x);

$d = bin2hex("\x00\x00" . pack("v", strlen($d)) . $o);
// 2
echo "2 -> ".$d."\n";
?>

只需删除函数
hash()

如果将此参数设置为true,hash将返回原始二进制数据,php试图将其解析为文本字符串,而您期望的是十六进制结果

不适用于php
根据(重点是我的):

计算数据的CRC(循环冗余校验)校验和。结果是一个无符号32位整数

您正在混淆以下两个方面:

  • 它的值-也可以看作长度为4的ASCII字符串
  • 其值的文本表示形式(在base 16中)-长度为8的字符串
>>crc=0x2B3257EE#zlib.crc32为文本返回的值
>>>类型(crc),crc
(, 724719598)
>>>
>>>[0,8,16,24]中移位位的[chr((crc>>移位位)&0xFF]
[“î”、“W”、“2”、“+”]
注释

  • 一种方法是将数字的4个字节转换成一个字符
  • 要从uint32值中获取一个字节,必须将uint32向右移动(),移动顺序为值([3,2,1,0])乘以8(字节中的位数)
    • 此外,为了消除不需要的字节(除最右边的字节外的任何字节),结果值也会与0xFF(255)进行AND运算
  • 由于尾数很少,字节按相反的顺序(从右到左)转换为字符
  • 第一个字符(
    “î”
    )看起来不一样,但它只是一个表示问题(在我的控制台和你的控制台中)
将其集成到您的代码中,您需要修改crc32b函数(并删除对哈希的任何进一步处理),以:

def crc32b(x):
crc=zlib.crc32(x)
返回“.join([0,8,16,24]]中移位位的[chr((crc>>移位位)&0xFF))
有关此一般主题的更多详细信息,请查看

@EDIT0

添加从十六进制表示形式开始的版本:

>>crc=0x2B3257EE
>>>crc_hex=“{:08X}”格式(crc)
>>>crc_十六进制
“2B3257EE”
>>>
>>>列表(范围(len(crc_hex)//2)中i的反向([chr(int(crc_hex[2*i]+crc_hex[2*i+1,16]))
[“î”、“W”、“2”、“+”]
  • 从我的观点来看,这是丑陋的,也是低效的(许多来回转换),但无论如何张贴,因为有些人有困难的工作位操作
  • 关键点是一次处理2个十六进制字符,并且只有在转换后才能反转

谢谢,但我需要编辑Python代码以获得相同的结果,而不是相反的结果。你会怎么做?这是一个更大的脚本的一部分,我需要在另一行使用输出。你会怎么做?我添加了步骤2。它们必须相等。@aws_学徒它是crc32b而不是crc32,正如你所看到的,函数中使用了zlib。嘿,这回答了你的问题吗?
    def crc32b(x):
        h = zlib.crc32(x)
        x='%08X' % (h & 0xffffffff,)
        return x.lower()

    t = "\t"
    gen = t.join(["1",
                  "100", # SAME VARIABLES 
                  "EUR",
                  "20190101",
                  "11111111",
                  "",
                  "",
                  "",
                  "Faktúra",
                  "1",
                  "SK6807200002891987426353",
                  "",
                  "0",
                  "0"]
                 )

    d = t.join([
        "", "1", gen])
    # 0
    print(f"0 -> {d}")
    hashD = crc32b(d.encode()) # OK

    hashD = hashD[::-1]
    # hashD = str(binascii.unhexlify(hashD))
    d = hashD + d
    # 1
    print(f"1 -> {d}")
    args = shlex.split("xz '--format=raw' '--lzma1=lc=3,lp=0,pb=2,dict=128KiB' -c -")
    process = subprocess.Popen(args, shell=False, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
                               stderr=subprocess.PIPE)
    output = process.communicate(d.encode())

    pack = "\x00\x00" + str(struct.pack("H", len(d))) + str(output[0])

    d = binascii.hexlify(pack.encode())
    # 2
    print(f"2 -> {d}")