我需要将一个 Python 函数转换成 C 函数,以便比较Python 和 C 代码的性能差异,具体Python 函数如下:
def decode(encstr):
# Number of characters in string should be even
# If it's not - remove last character
if (len(encstr) % 2 != 0):
encstr = encstr[:-1] # length of string - 1
strlen = len(encstr)
i = 0
decrypted = []
while (i < strlen):
# get character at position i
cc = encstr[i];
# get integer representing the Unicode code point of the character
cch = ord(cc)
nch = ord(encstr[i + 1])
if cc == '0':
v = nch
elif cc == 'z':
v = cch - nch + 56
elif cc in ['1', '2', '3', '4', '5', '6', '7', '8', '9']:
v = (cch - 49) * 25 + 181 - nch
else:
v = cch - nch
if(v < 0):
v = (v % 256) + 256
if v > 255:
v = v % 256
# append the decrypted character
decrypted.append(chr(v))
i += 2
return ''.join(decrypted)
2、解决方案
有两种方法可以将此 Python 函数转换为 C 函数:
- 方法一:使用现有的 C 扩展来提高性能,例如 NumPy。
import numpy as np
def decode(encstr):
arr = np.array(encstr, 'c').view(np.uint8) # to ASCII codes
out = np.empty(len(encstr) / 2, np.uint8)
out[:] = arr[::2] - arr[1::2] # v = cch - nch, default case
mask = np.where(arr == ord('0'))[0] # cc == '0'
out[mask / 2] = arr[mask + 1] # v = nch
mask = np.where(arr == ord('z'))[0] # cc == 'z'
out[mask / 2] = arr[mask] - arr[mask + 1] + 56 # cch - nch + 56
mask = np.where(np.logical_and(arr >= ord('1'), arr <= ord('9')))[0] # cc in ['1'..'9']
out[mask / 2] = (arr[mask] - ord('1')) * 25 + 181 - arr[mask + 1] # (cch - ord('1')) * 25 + 181 - nch
return ''.join(out.view('c')) # back from ASCII codes
- 方法二:直接将 Python 函数翻译成 C 函数,代码如下:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <assert.h>
void decode( const char *encstr,
size_t decrypt_len,
char decrypt[ static decrypt_len ] )
{
assert( encstr );
size_t len = strlen( encstr );
//
// Create a local copy of the encrypted string, since we want to
// modify the input below
//
char lencstr[len + 1];
strcpy( lencstr, encstr );
if ( len % 2 )
lencstr[len - 1] = 0;
const char *cc = lencstr;
const char *nc = cc + 1;
while ( *cc )
{
int v;
if ( *cc == '0' )
v = *nc;
else if ( *cc == 'z' )
v = *cc - *nc + 56;
else if ( isdigit( *cc ) )
v = (*cc - 49) * 25 + 181 - *nc;
else
v = *cc - *nc;
if ( v < 0 )
v = ( v % 256 ) + 256;
else if ( v > 255 )
v = v % 256;
*decrypt++ = (char) v;
cc += 2;
nc += 2;
}
*decrypt = 0;
}
int main( void )
{
const char *enc = "0T1M1L1BtT1L1BtT1TtT1B1T1H1E1I1PtT1B2Z1C1L1G1NtTt"
"NtT2Z1M1T2ZtT2W1PtT1T1C1PtTzutT2Z1P1B2Z1L1G1N";
char dec[ strlen(enc) + 1 ];
printf( "Encrypted string: %s\n", enc );
decode( enc, sizeof dec, dec );
printf( "Decrypted string: %s\n", dec );
return 0;
}

1285

被折叠的 条评论
为什么被折叠?



