ctypes memset, libc/msvcrt. , 20 32- . 64- , , 36 . PyStringObject:
typedef struct {
Py_ssize_t ob_refcnt;
struct _typeobject *ob_type;
Py_ssize_t ob_size;
long ob_shash;
int ob_sstate;
char ob_sval[1];
} PyStringObject;
, 5 * 4 = 20 32- , 8 * 4 + 4 = 36 64- Linux 8 * 3 + 4 * 2 = 32 64- Windows, , sys.getsizeof. , , GC ( , id), __sizeof__. , .
. CPython , 1 , . :
>>> a = 'abcdef'
>>> bufsize = len(a) + 1
>>> offset = sys.getsizeof(a) - bufsize
>>> ctypes.memset(id(a) + offset, 0, bufsize)
3074822964L
>>> a
'\x00\x00\x00\x00\x00\x00'
Edit
PyStringObject. ob_sstate. 0, , , - . , ASCII , , ( , ).
from ctypes import *
class PyStringObject(Structure):
_fields_ = [
('ob_refcnt', c_ssize_t),
('ob_type', py_object),
('ob_size', c_ssize_t),
('ob_shash', c_long),
('ob_sstate', c_int),
]
def zerostr(s):
"""zero a non-interned string"""
if not isinstance(s, str):
raise TypeError(
"expected str object, not %s" % type(s).__name__)
s_obj = PyStringObject.from_address(id(s))
if s_obj.ob_sstate > 0:
raise RuntimeError("cannot zero interned string")
s_obj.ob_shash = -1
offset = sizeof(PyStringObject)
memset(id(s) + offset, 0, len(s))
:
>>> s = 'abcd'
>>> zerostr(s)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<string>", line 10, in zerostr
RuntimeError: cannot zero interned string
>>> s = raw_input()
abcd
>>> zerostr(s)
>>> s
'\x00\x00\x00\x00'