#101 Python 国密(sm3)
安全 加密 sm3 Python 2021-10-03sm3 是我国设计的一种哈希算法,根据维基百科信息,大致相当于 sha256。
coding in a complicated world
sm3 是我国设计的一种哈希算法,根据维基百科信息,大致相当于 sha256。
一个不值一提的小问题:
有个地方使用 hash 方法来做哈希计算,将字符串转换成一个数值,但是发现改用 Python 3 之后,这个值每次运行都不一样了。
开发时,有时候我们需要将任意字符串映射成一个数字或字符串,这就是哈希。
效果:
![]()
PyFrameObject
// Include/cpython/frameobject.h
struct _frame {
PyObject_VAR_HEAD
struct _frame *f_back; /* previous frame, or NULL */
PyCodeObject *f_code; /* code segment */
PyObject *f_builtins; /* builtin symbol table (PyDictObject) */
PyObject *f_globals; /* global symbol table (PyDictObject) */
PyObject *f_locals; /* local symbol table (any mapping) */
PyObject **f_valuestack; /* points after the last local */
/* Next free slot in f_valuestack. Frame creation sets to f_valuestack.
Frame evaluation usually NULLs it, but a frame that yields sets it
to the current stack top. */
PyObject **f_stacktop;
PyObject *f_trace; /* Trace function */
char f_trace_lines; /* Emit per-line trace events? */
char f_trace_opcodes; /* Emit per-opcode trace events? */
/* Borrowed reference to a generator, or NULL */
PyObject *f_gen;
int f_lasti; /* Last instruction if called */
/* Call PyFrame_GetLineNumber() instead of reading this field
directly. As of 2.3 f_lineno is only valid when tracing is
active (i.e. when f_trace is set). At other times we use
PyCode_Addr2Line to calculate the line from the current
bytecode index. */
int f_lineno; /* Current line number */
int f_iblock; /* index in f_blockstack */
char f_executing; /* whether the frame is still executing */
PyTryBlock f_blockstack[CO_MAXBLOCKS]; /* for try and loop blocks */
PyObject *f_localsplus[1]; /* locals+stack, dynamically sized */
};
// Include/pyframe.h
typedef struct _frame PyFrameObject;
def sum(a, b):
return a + b
def test():
print('hello world')
print(sum(1, 2))
import dis
dis.dis(sum)
dis.dis(test)
2 0 LOAD_FAST 0 (a)
2 LOAD_FAST 1 (b)
4 BINARY_ADD
6 RETURN_VALUE
5 0 LOAD_GLOBAL 0 (print)
2 LOAD_CONST 1 ('hello world')
4 CALL_FUNCTION 1
6 POP_TOP
6 8 LOAD_GLOBAL 0 (print)
10 LOAD_GLOBAL 1 (sum)
12 LOAD_CONST 2 (1)
14 LOAD_CONST 3 (2)
16 CALL_FUNCTION 2
18 CALL_FUNCTION 1
20 POP_TOP
22 LOAD_CONST 0 (None)
24 RETURN_VALUE
行号,指令偏移,指令,参数,参数值(参考)
查看字节码:
sum.__code__.co_code
sum.__code__.co_varnames
sum.__code__.co_consts
sum.__code__.co_names
set
我都有点怀疑我这个学习计划是否是正确的。
同样的废话,就懒得说了,只说有价值的信息。
汇总了一下,所有的类型:
PyAsyncGen_TypePyBaseObject_TypePyBlake2_BLAKE2bTypePyBlake2_BLAKE2sTypePyBool_TypePyBufferedIOBase_TypePyBufferedRandom_TypePyBufferedReader_TypePyBufferedRWPair_TypePyBufferedWriter_TypePyByteArrayIter_TypePyByteArray_TypePyBytesIO_TypePyBytesIter_TypePyBytes_TypePyCallIter_TypePyCapsule_TypePyCArg_TypePyCArray_TypePyCArrayType_TypePyCData_TypePyCell_TypePyCField_TypePyCFuncPtr_TypePyCFuncPtrType_TypePyCFunction_TypePyClassMethodDescr_TypePyClassMethod_TypePyCMethod_TypePyCode_TypePyComplex_TypePyContextTokenMissing_TypePyContextToken_TypePyContext_TypePyContextVar_TypePyCoro_TypePyCPointer_TypePyCPointerType_TypePyCSimpleType_TypePyCStgDict_TypePyCStructType_TypePyCThunk_TypePyCursesWindow_TypePyCursesWindow_Type;PyDictItems_TypePyDictIterItem_TypePyDictIterKey_TypePyDictIterValue_TypePyDictKeys_TypePyDictProxy_TypePyDictRevIterItem_TypePyDictRevIterKey_TypePyDictRevIterValue_TypePyDict_TypePyDictValues_TypePyEllipsis_TypePyEnum_TypePyFileIO_TypePyFileIO_Type;PyFilter_TypePyFloat_TypePyFrame_TypePyFrozenSet_TypePyFunction_TypePy_GenericAliasTypePyGen_TypePyGetSetDescr_TypePyHKEY_TypePyIncrementalNewlineDecoder_TypePyInstanceMethod_TypePyIOBase_TypePyListIter_TypePyListRevIter_TypePyList_TypePyLongRangeIter_TypePyLong_TypePyMap_TypePyMemberDescr_TypePyMemoryView_TypePyMethodDescr_TypePyMethod_TypePyModuleDef_TypePyModule_TypePyODictItems_TypePyODictIter_TypePyODictKeys_TypePyODict_TypePyODictValues_TypePyPickleBuffer_TypePyProperty_TypePyRangeIter_TypePyRange_TypePyRawIOBase_TypePyReversed_TypePySeqIter_TypePySetIter_TypePySet_TypePySlice_TypePyStaticMethod_TypePyStdPrinter_TypePySTEntry_TypePyStringIO_TypePyST_TypePySuper_TypePyTextIOBase_TypePyTextIOWrapper_TypePyTraceBack_TypePyTupleIter_TypePyTuple_TypePyType_TypePyUnicodeIter_TypePyUnicode_TypePyWindowsConsoleIO_TypePyWindowsConsoleIO_Type;PyWrapperDescr_TypePyZip_Type微信公众号上看到公众号机器学习实验室的系列文章 Python 机器学习算法实现, 感觉非常好,就学习学习吧!
dict
INIT_TYPE(&PyDict_Type, "dict");
SETBUILTIN("dict", &PyDict_Type);
PyTypeObject PyDict_Type 的定义在 Objects/dictobject.c 中。
Include/cpython/dictobject.h
typedef struct {
PyObject_HEAD
/* Number of items in the dictionary */
Py_ssize_t ma_used;
/* Dictionary version: globally unique, value change each time
the dictionary is modified */
uint64_t ma_version_tag;
PyDictKeysObject *ma_keys;
/* If ma_values is NULL, the table is "combined": keys and values
are stored in ma_keys.
If ma_values is not NULL, the table is splitted:
keys are stored in ma_keys and values are stored in ma_values */
PyObject **ma_values;
} PyDictObject;
setdefault#define DICT_SETDEFAULT_METHODDEF \
{"setdefault", (PyCFunction)(void(*)(void))dict_setdefault, METH_FASTCALL, dict_setdefault__doc__},
static PyObject *
dict_setdefault(PyDictObject *self, PyObject *const *args, Py_ssize_t nargs)
{
PyObject *return_value = NULL;
PyObject *key;
PyObject *default_value = Py_None;
if (!_PyArg_CheckPositional("setdefault", nargs, 1, 2)) {
goto exit;
}
key = args[0];
if (nargs < 2) {
goto skip_optional;
}
default_value = args[1];
skip_optional:
return_value = dict_setdefault_impl(self, key, default_value);
exit:
return return_value;
}
static PyObject *
dict_setdefault_impl(PyDictObject *self, PyObject *key,
PyObject *default_value)
/*[clinic end generated code: output=f8c1101ebf69e220 input=0f063756e815fd9d]*/
{
PyObject *val;
val = PyDict_SetDefault((PyObject *)self, key, default_value);
Py_XINCREF(val);
return val;
}
list
cpython/Include/cpython/tupleobject.h
INIT_TYPE(&PyList_Type, "list");
SETBUILTIN("list", &PyList_Type);
PyTypeObject PyList_Type 的定义在 Objects/listobject.c 中。
相关的方法在 #define LIST_.+_METHODDEF 的定义中,比如 extend 方法:
#define LIST_APPEND_METHODDEF \
{"append", (PyCFunction)list_append, METH_O, list_append__doc__},
static PyObject *
list_append(PyListObject *self, PyObject *object)
/*[clinic end generated code: output=7c096003a29c0eae input=43a3fe48a7066e91]*/
{
if (app1(self, object) == 0)
Py_RETURN_NONE;
return NULL;
}
static int
app1(PyListObject *self, PyObject *v)
{
Py_ssize_t n = PyList_GET_SIZE(self);
assert (v != NULL);
if (n == PY_SSIZE_T_MAX) {
PyErr_SetString(PyExc_OverflowError,
"cannot add more objects to list");
return -1;
}
if (list_resize(self, n+1) < 0)
return -1;
Py_INCREF(v);
PyList_SET_ITEM(self, n, v);
return 0;
}
tuple
INIT_TYPE(&PyTuple_Type, "tuple");
SETBUILTIN("tuple", &PyTuple_Type);
**cpython/Include/cpython/tupleobject.h**
typedef struct {
PyObject_VAR_HEAD
/* ob_item contains space for 'ob_size' elements.
Items must normally not be NULL, except during construction when
the tuple is not yet visible outside the function that builds it. */
PyObject *ob_item[1];
} PyTupleObject;
当然,与之对应的 PyTypeObject PyTuple_Type 定义在 Objects/tupleobject.c,就不贴出来了。
PyTuple_SET_ITEM 似乎是在完成内存初始化的空间内填充元素时使用的。
tuple 类型只有两个成员方法:count, index
#define TUPLE_INDEX_METHODDEF \
{"index", (PyCFunction)(void(*)(void))tuple_index, METH_FASTCALL, tuple_index__doc__},
#define TUPLE_COUNT_METHODDEF \
{"count", (PyCFunction)tuple_count, METH_O, tuple_count__doc__},
static PyMethodDef tuple_methods[] = {
TUPLE___GETNEWARGS___METHODDEF
TUPLE_INDEX_METHODDEF
TUPLE_COUNT_METHODDEF
{"__class_getitem__", (PyCFunction)Py_GenericAlias, METH_O|METH_CLASS, PyDoc_STR("See PEP 585")},
{NULL, NULL} /* sentinel */
};
Py_INCREF
Py_DECREF
Py_XINCREF
Py_XDECREF