简体   繁体   English

Different Results Passing byte-array arguments to C Function in Python via ctypes vs. calling the function in C

[英]Different Results Passing byte-array arguments to C Function in Python via ctypes vs. calling the function in C

I am trying to use a function from a C library in python using ctypes .我正在尝试使用 python 中的 C 库中的 function 使用ctypes The called function calculates a SHA256 hash output from the input of fixed length 38 and a given state of the hash function. The called function calculates a SHA256 hash output from the input of fixed length 38 and a given state of the hash function.

The problem now is, that I get different results calling the function with python and calling it within a C program.现在的问题是,我得到不同的结果,调用 function 和 python 并在 C 程序中调用它。 Is there a difference in encoding of uint8 of C and byte-array strings from python? C 的uint8编码和 python 的字节数组字符串的编码有区别吗? Or am I missing something else?还是我错过了其他东西?

Here the function call in C:这里 function 调用 C:

uint8_t input[38] = {"0"};
uint8_t state[40] = {"0"};
uint8_t output[32] = {"0"};

sha256_inc_finalize(output, state, input, 38);

And the function call in python (3.10.4): python (3.10.4) 中的 function 调用:

import ctypes

sha = ctypes.CDLL('/path/to/lib/sha_lib.so')
func = sha.sha256_inc_finalize

func.argtypes = [ctypes.c_char_p, ctypes.c_char_p, ctypes.c_char_p, ctypes.c_size_t]    

out = ctypes.create_string_buffer(b'00000000000000000000000000000000', size=32)
state = ctypes.create_string_buffer(b'0000000000000000000000000000000000000000', size=40) 
input = b'00000000000000000000000000000000000000'
func(out, state, input, 38)

I do not include the value of output after the call of sha256_inc_finalize here because it is just a hash value.我这里不包括调用output之后的sha256_inc_finalize的值,因为它只是一个 hash 值。

Any clue on what's going on here is much appreciated!任何关于这里发生的事情的线索都非常感谢!

EDIT:编辑:

The hash of the function called from C is从 C 调用的 function 的 hash 是

3ca2f9f4 37712b50 7b046090 4497276a 81199415 1a7760a3 60840c92 747c8bbe

while the call via python outputs:而通过 python 的调用输出:

133cc1c1 4a8bd095 37e022d1 829a2261 1a0aab38 35a0c2ab 291a088e bb2d1c82

Although not the case here, [SO]: C function called from Python via ctypes returns incorrect value (@CristiFati's answer) .虽然这里不是这种情况, [SO]: C function 从 Python 通过 ctypes 调用返回错误值(@CristiFati's

You claim you got some results but you didn't show how ( AFAIC those pieces of code could be buggy and also the source of the problem).你声称你得到了一些结果,但你没有展示如何( AFAIC这些代码可能是错误的,也是问题的根源)。

Anyway, in order to create a MCVE ( [SO]: How to create a Minimal, Reproducible Example (reprex (mcve)) ), I had to build a couple of files from [GitHub]: sphincs/spincsplus - sphincsplus in order to get a libsha2.so that I could work with.无论如何,为了创建一个MCVE[SO]: How to create a Minimal, Reproducible Example (reprex (mcve)) ),我必须从[GitHub] 构建几个文件:sphincs/spincsplus - sphincsplus为了得到一个libsha2.so我可以使用。

code00.py :代码00.py

#!/usr/bin/env python

import ctypes as cts
import sys


DLL_NAME = "/mnt/e/Work/Dev/GitHub/CristiFati/sphincsplus/libsha2.{:s}".format("dll" if sys.platform[:3].lower() == "win" else "so")
BytePtr = cts.POINTER(cts.c_ubyte)


def hex_dump(arr, group=4, text=""):
    print("\n{:s}".format(text if text else ""))
    print(arr)
    pat = "{:02X}" * group
    cnt, last = divmod(len(arr), group)
    for i in range(cnt):
        print(pat.format(*arr[i * group:(i + 1) * group]), end=" ")
    print(("{:02X}" * last).format(*arr[cnt * group:]))


def main(*argv):
    dll = cts.CDLL(DLL_NAME)
    sha256_inc_finalize = dll.sha256_inc_finalize
    sha256_inc_finalize.argtypes = (BytePtr, BytePtr, BytePtr, cts.c_size_t)
    sha256_inc_finalize.restype = None

    inp_len = 38
    inp = b"0" * inp_len
    #inp = b"0" + b"\x00" * (inp_len - 1)
    outp_len = 32
    outp = cts.create_string_buffer(outp_len)
    state_len = 40
    state = cts.create_string_buffer(state_len)
    sha256_inc_finalize(cts.cast(outp, BytePtr), cts.cast(state, BytePtr), cts.cast(inp, BytePtr), inp_len)
    hex_dump(inp, text="input:")
    hex_dump(state, text="state:")
    hex_dump(outp, text="output:")


if __name__ == "__main__":
    print("Python {:s} {:03d}bit on {:s}\n".format(" ".join(elem.strip() for elem in sys.version.split("\n")),
                                                   64 if sys.maxsize > 0x100000000 else 32, sys.platform))
    rc = main(*sys.argv[1:])
    print("\nDone.\n")
    sys.exit(rc)

Output : Output

 (qaic-env) [cfati@cfati-5510-0:/mnt/e/Work/Dev/StackOverflow/q073866657]> python code00.py Python 3.8.10 (default, Jun 22 2022, 20:18:18) [GCC 9.4.0] 064bit on linux input: b'00000000000000000000000000000000000000' 30303030 30303030 30303030 30303030 30303030 30303030 30303030 30303030 30303030 3030 state: <ctypes.c_char_Array_40 object at 0x7fe69dde58c0> 51B8117D 8B54D933 939F51DA E3798764 07FAB6C2 31CFF0B8 F3F2CD3E 9903EC84 00000000 00000000 output: <ctypes.c_char_Array_32 object at 0x7fe69dd069c0> 51B8117D 8B54D933 939F51DA E3798764 07FAB6C2 31CFF0B8 F3F2CD3E 9903EC84 Done.

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用ctypes将python对象作为参数传递给C / C ++函数 - Passing python objects as arguments to C/C++ function using ctypes 通过Python ctypes调用C函数:为什么将uint传递给期望size_t的函数有效? - Calling C functions via Python ctypes: why does passing uints to a function expecting size_t work? 通过C ++在Python函数中传递参数 - Passing arguments in Python function via C++ 在 Python 中,如何使用 ctypes 将回调数组作为参数传递给 C 函数? - In Python, how to pass a callback array as arguments to a C function using ctypes? 使用ctypes将python数组传递给c ++函数 - passing python array to c++ function using ctypes Python CTYPE:在C中使用自定义类型调用函数 - Python ctypes: calling a function with custom types in c 使用 ctypes 在 python 中调用 C++ function - Calling the C++ function in python using ctypes 使用ctypes从python调用C函数 - Calling C function from python using ctypes 高效的矩阵向量乘法:直接在Python中进行多线程与使用ctypes绑定多线程C函数 - Efficient Matrix-Vector Multiplication: Multithreading directly in Python vs. using ctypes to bind a multithreaded C function 是否通过 python 中的 ctypes 调用 c function 释放 GIL - Does calling a c function via ctypes in python release the GIL during execution of the C code
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM