ISAAC cipher in python - python

Does anyone have any working implementations of the ISAAC cipher in python?
I tried to find this, but it seems no one ever did it.
Thanks.

I read some code examples on the ISAAC home page and the code appears straightforward to implement. If you need it in pure Python there are several examples in other languages to guide your porting effort.
Another way of using isaac() from Python is to build the C code as a shared library and access it via the ctypes module, which is standard in 2.5+, but can be found on PyPI for earlier versions. This should also perform much better than a direct port in pure Python.
Here's an example of building the C version of isaac() as a shared library and using it via ctypes. First you need to download rand.c, rand.h, and standard.h from the author's website, then build:
% gcc -shared -fPIC -o libisaac.so rand.c
Here is the Python code. Note that the sizes of the fields in the RandCtx are dependent on whether the code is built for 32- or 64-bit platform. I tested on 64-bit Ubuntu. For 32-bit you'd need to change all of the fields to use c_uint32:
from ctypes import *
class RandCtx(Structure):
RANDSIZL = 8
RANDSIZ = 1 << RANDSIZL
_fields_ = [
('randcnt', c_uint64),
('randrsl', c_uint64 * RANDSIZ),
('randmem', c_uint64 * RANDSIZ),
('randa', c_uint64),
('randb', c_uint64),
('randc', c_uint64)
]
ctx = RandCtx()
lib = cdll.LoadLibrary('./libisaac.so')
lib.randinit(byref(ctx), 0)
lib.isaac(byref(ctx))
for i in xrange(4):
print ctx.randrsl[i]
Output:
% python isaac.py
14012348966175605106
8193820543905647488
4194352129441799609
12121047914186473054

Related

Unable to use pip modules with PyO3

Recently I have been working on a project that involves generating docx files. Since Rust's docx support is still quite immature, I've decided to use Python's python-docx module via PyO3.
Here's my code so far:
extern crate pyo3;
use pyo3::prelude::*;
(...)
// Initialize some Python
let gil = Python::acquire_gil();
let py = gil.python();
let docx = PyModule::import(py, "docx")?;
let document = docx.Document();
Unfortunately, I'm running into two pretty serious errors.
Error #1:
let docx = PyModule::import(py, "docx")?;
^ cannot use the `?` operator in a function that returns `std::string::String
Error #2:
let document = docx.Document();
^^^^^^^^ method not found in `&pyo3::prelude::PyModule`
How do I solve these errors?
N.B. Yes, I have made sure that python-docx is installed. It's located in /home/<my username>/.local/lib/python3.8/site-packages

Is there a built-in way to use inline C code in Python?

Even if numba, cython (and especially cython.inline) exist, in some cases, it would be interesting to have inline C code in Python.
Is there a built-in way (in Python standard library) to have inline C code?
PS: scipy.weave used to provide this, but it's Python 2 only.
Directly in the Python standard library, probably not. But it's possible to have something very close to inline C in Python with the cffi module (pip install cffi).
Here is an example, inspired by this article and this question, showing how to implement a factorial function in Python + "inline" C:
from cffi import FFI
ffi = FFI()
ffi.set_source("_test", """
long factorial(int n) {
long r = n;
while(n > 1) {
n -= 1;
r *= n;
}
return r;
}
""")
ffi.cdef("""long factorial(int);""")
ffi.compile()
from _test import lib # import the compiled library
print(lib.factorial(10)) # 3628800
Notes:
ffi.set_source(...) defines the actual C source code
ffi.cdef(...) is the equivalent of the .h header file
you can of course add some cleaning code after, if you don't need the compiled library at the end (however, cython.inline does the same and the compiled .pyd files are not cleaned by default, see here)
this quick inline use is particularly useful during a prototyping / development phase. Once everything is ready, you can separate the build (that you do only once), and the rest of the code which imports the pre-compiled library
It seems too good to be true, but it seems to work!

Speed difference in Python compiled with MS C vs. MinGW

On my Windows 7 machine, I use two CPython implementations:
1) WinPython distribution, which is compiled with MSC v.1500 64bit
2) MinGW-builds, which is compiled with MinGW/GCC 4.9.1 64bit
I've tried the MinGW-built version to compile some C extensions for Python, which need to be built with the same compiler as Python itself to function properly.
Now consider the following test script, which generates a random dictionary and repeatedly pickles&unpickles it.
import pickle, cPickle, random
from time import clock
def timeit(mdl, d, num=100, bestof=10):
times = []
for _ in range(bestof):
start = clock()
for _ in range(num):
mdl.loads(mdl.dumps(d))
times.append(clock() - start)
return min(times)
def gen_dict(entries=100, keylength=5):
formatstr = "{:0%dx}" % keylength
d = {}
for _ in range(entries):
rn = random.randrange(16**keylength) # 'keylength'-digit hex number
# format into string of length 5 as key, decimal value as value
d[formatstr.format(rn)] = rn
return d
def main(entries=100, keylength=5, num=100, bestof=10):
print "Dict size: %d entries, keylength: %d" % (entries, keylength)
print ("Test is %d times pack/unpack. "
"Take best time out of %d runs\n" % (num, bestof))
d = gen_dict(entries, keylength)
for mdl in [pickle, cPickle]:
print "%s: %f s" % (mdl.__name__, timeit(mdl, d, num, bestof))
if __name__ == "__main__":
main()
MSC CPython gave me
Dict size: 100 entries, keylength: 5
Test is 100 times pack/unpack. Take best time out of 10 runs
pickle: 0.107798 s
cPickle: 0.011802 s
and MinGW/GCC CPython gave me
Dict size: 100 entries, keylength: 5
Test is 100 times pack/unpack. Take best time out of 10 runs
pickle: 0.103065 s
cPickle: 0.075507 s
So the cPickle module (a standard library C extension for Python) is 6.4x slower on MinGW than on MSC.
I haven't investigated further (i.e. tested more C extensions), but I am quite surprised.
Is this to be expected?
Will other C extensions run in general slower on a Python/MinGW toolchain?
I have used MSYS2 and the MinGW-w64 tool chain to compile a large CPU-bound extension. It did not run unusually slow; I actually think it runs faster than MSC. One possible cause for slow extensions: the Mingw32CCompiler class contained in the file cygwincompiler.py specified -O optimization. I changed that to -O2 and the performance improved.
I use the extension with the standard CPython as distributed from python.org.
Update
I tried your sample program on MSYS2. There are two versions of Python 2.7 available: one that is part of the MSYS2 distribution and the other is part of the MinGW-w64 tool-chain. The version that is included with MSYS2 does not exhibit the performance issue while the version included with MinGW-w64 does exhibit the performance issue with cPickle. Since the MSYS2 version is compiled by the GCC included in MinGW-w64, I believe the slowdown is related to the specific options used when compiling the MinGW version. I haven't looked at the source code for both versions to see what causes the difference.
Regarding the requirement to use the same version of the compiler for an extension as the Python interpreter - the answer is "It depends....". The problem occurs because there are some minor differences between the C runtime library that is used by each major version of MSC. IIRC, one of the differences can break the passing of file handles between Python and the extension. If you don't use any calls that rely on the differences, then you can mix compiler versions. Since there isn't a definitive list of differences, nor a way to prevent an extension from making those calls that are different, the only guaranteed answer is not mixing versions. My extension doesn't (I think) use any C runtime calls that are different. It only uses the Python C-API for all IO and memory management. I have successfully mixed compiler versions when testing but I still prefer not to do so.
I'm still experimenting with the MSYS2/MinGW-w64 approach to building my extension and using it with an MSC-compiled version of CPython. It does appear to work and it performs as expected.

How to make Python Extensions for Windows for absolute beginners

I've been looking around the internet trying to find a good step by step guide to extend Python in Windows, and I haven't been able to find something for my skill level.
let's say you have some c code that looks like this:
#include <stdio.h>
#include <math.h>
double valuex(float value, double rate, double timex)
{
float value;
double rate, timex;
return value / (double) pow ((1 + rate), (timex));
}
and you want to turn that into a Python 3 module for use on a windows (64bit if that makes a difference) system. How would you go about doing that? I've looked up SWIG and Pyrex and in both circumstances they seem geared towards the unix user. With Pyrex I am not sure if it works with Python 3.
I'm just trying to learn the basics of programing, using some practical examples.
Lastly, if there is a good book that someone can recommend for learning to extend, I would greatly appreciate it.
Thank you.
Cython (Pyrex with a few kinks worked out and decisions made for practicality) can use one code base to make Python 2 and Python 3 modules. It's a really great choice for making libraries for 2 and 3. The user guide explains how to use it, but it doesn't demystify Windows programming or C or Python or programming in general, thought it can simplify some things for you.
SWIG can be hard to work with when you run into a problem and will not be especially conducive to creating a very native-feeling, idiomatic binding of the C you are relying on. For that, you would need to re-wrap the wrapper in Python, at which point it might have been nicer just to use Cython. It can be nice for bindings that you cannot dedicate enough work to make truly nice, and is convenient in that you can expose your API to many languages at once in it.
Depending on what you're trying to do, building your "extension" as a simple DLL and accessing it with ctypes could be, by far, the simplest approach.
I used your code, slightly adjusted and saved as mydll.c:
#include <stdio.h>
#include <math.h>
#define DLL_EXPORT __declspec(dllexport)
DLL_EXPORT double valuex(float value, double rate, double timex)
{
float value;
double rate, timex;
return value / (double) pow ((1 + rate), (timex));
}
I downloaded the Tiny C Compiler and invoked with this command.
tcc -shared mydll.c
(I believe adding -rdynamic would avoid the need to sprinkle DLL_EXPORT all over your function defs.)
This generated mydll.dll. I then ran Python:
Python 3.1.2 (r312:79149, Mar 21 2010, 00:41:52) ... on win32
>>> from ctypes import *
>>> mydll = cdll.mydll
>>> valuex = mydll.valuex
>>> valuex.argtypes = [c_float, c_double, c_double]
>>> valuex.restype = c_double
>>> valuex(1.2, 2.3, 3.4)
2.0470634033800796e-21
A start would be the documentation Building C and C++ Extensions on Windows.
Well, the easiest way to create Python plugins is to use C++ and Boost.Python. In your example, the extension module would look as simple as this:
#include <boost/python.hpp>
using namespace boost::python;
// ... your valuex function goes here ...
BOOST_PYTHON_MODULE(yourModuleName)
{
def("valuex", valuex, "an optional documentation string");
}
Boost.Python is available on the popular operating systems and should work with Python 3, too (not tested it, though, support was added in 2009).
Regarding SWIG: It is not for Unix only. You can download precompiled Windows binaries or compile it yourself with MinGW/MSYS.
You could as well try out Cython which is said to be Python 3 compatible.
At PyCon 2009, I gave a talk on how to write Python C extensions: A Whirlwind Excursion through Python C Extensions. There's nothing specific to Windows in it, but it covers the basic structure of an extension.

calling Objective C functions from Python?

Is there a way to dynamically call an Objective C function from Python?
For example, On the mac I would like to call this Objective C function
[NSSpeechSynthesizer availableVoices]
without having to precompile any special Python wrapper module.
As others have mentioned, PyObjC is the way to go. But, for completeness' sake, here's how you can do it with ctypes, in case you need it to work on versions of OS X prior to 10.5 that do not have PyObjC installed:
import ctypes
import ctypes.util
# Need to do this to load the NSSpeechSynthesizer class, which is in AppKit.framework
appkit = ctypes.cdll.LoadLibrary(ctypes.util.find_library('AppKit'))
objc = ctypes.cdll.LoadLibrary(ctypes.util.find_library('objc'))
objc.objc_getClass.restype = ctypes.c_void_p
objc.sel_registerName.restype = ctypes.c_void_p
objc.objc_msgSend.restype = ctypes.c_void_p
objc.objc_msgSend.argtypes = [ctypes.c_void_p, ctypes.c_void_p]
# Without this, it will still work, but it'll leak memory
NSAutoreleasePool = objc.objc_getClass('NSAutoreleasePool')
pool = objc.objc_msgSend(NSAutoreleasePool, objc.sel_registerName('alloc'))
pool = objc.objc_msgSend(pool, objc.sel_registerName('init'))
NSSpeechSynthesizer = objc.objc_getClass('NSSpeechSynthesizer')
availableVoices = objc.objc_msgSend(NSSpeechSynthesizer, objc.sel_registerName('availableVoices'))
count = objc.objc_msgSend(availableVoices, objc.sel_registerName('count'))
voiceNames = [
ctypes.string_at(
objc.objc_msgSend(
objc.objc_msgSend(availableVoices, objc.sel_registerName('objectAtIndex:'), i),
objc.sel_registerName('UTF8String')))
for i in range(count)]
print voiceNames
objc.objc_msgSend(pool, objc.sel_registerName('release'))
It ain't pretty, but it gets the job done. The final list of available names is stored in the voiceNames variable above.
2012-4-28 Update: Fixed to work in 64-bit Python builds by making sure all parameters and return types are passed as pointers instead of 32-bit integers.
Since OS X 10.5, OS X has shipped with the PyObjC bridge, a Python-Objective-C bridge. It uses the BridgeSupport framework to map Objective-C frameworks to Python. Unlike, MacRuby, PyObjC is a classical bridge--there is a proxy object on the python side for each ObjC object and visa versa. The bridge is pretty seamless, however, and its possible to write entire apps in PyObjC (Xcode has some basic PyObjC support, and you can download the app and file templates for Xcode from the PyObjC SVN at the above link). Many folks use it for utilities or for app-scripting/plugins. Apple's developer site also has an introduction to developing Cocoa applications with Python via PyObjC which is slightly out of date, but may be a good overview for you.
In your case, the following code will call [NSSpeechSynthesizer availableVoices]:
from AppKit import NSSpeechSynthesizer
NSSpeechSynthesizer.availableVoices()
which returns
(
"com.apple.speech.synthesis.voice.Agnes",
"com.apple.speech.synthesis.voice.Albert",
"com.apple.speech.synthesis.voice.Alex",
"com.apple.speech.synthesis.voice.BadNews",
"com.apple.speech.synthesis.voice.Bahh",
"com.apple.speech.synthesis.voice.Bells",
"com.apple.speech.synthesis.voice.Boing",
"com.apple.speech.synthesis.voice.Bruce",
"com.apple.speech.synthesis.voice.Bubbles",
"com.apple.speech.synthesis.voice.Cellos",
"com.apple.speech.synthesis.voice.Deranged",
"com.apple.speech.synthesis.voice.Fred",
"com.apple.speech.synthesis.voice.GoodNews",
"com.apple.speech.synthesis.voice.Hysterical",
"com.apple.speech.synthesis.voice.Junior",
"com.apple.speech.synthesis.voice.Kathy",
"com.apple.speech.synthesis.voice.Organ",
"com.apple.speech.synthesis.voice.Princess",
"com.apple.speech.synthesis.voice.Ralph",
"com.apple.speech.synthesis.voice.Trinoids",
"com.apple.speech.synthesis.voice.Vicki",
"com.apple.speech.synthesis.voice.Victoria",
"com.apple.speech.synthesis.voice.Whisper",
"com.apple.speech.synthesis.voice.Zarvox"
)
(a bridged NSCFArray) on my SL machine.
Mac OS X from 10.5 onward has shipped with Python and the objc module that will let you do what you want.
An example:
from Foundation import *
thing = NSKeyedUnarchiver.unarchiveObjectWithFile_(some_plist_file)
You can find more documentation here.
You probably want PyObjC. That said, I've never actually used it myself (I've only ever seen demos), so I'm not certain that it will do what you need.

Categories