将函数从Python转换为C.

时间:2013-11-22 14:24:54

标签: python c

这个函数是用python编写的。我试图测量Python和C之间的性能。 流利的C能否帮助将此功能转换为C?

输入字符串

0T1M1L1BtT1L1BtT1TtT1B1T1H1E1I1PtT1B2Z1C1L1G1NtTtNtT2Z1M1T2ZtT2W1PtT1T1C1PtTzutT2Z1P1B2Z1L1G1N

解码后的输出

这是一个示例字符串&我们=测试

这是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 个答案:

答案 0 :(得分:3)

为什么不使用已编写的扩展,而不是编写自己的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

这缺少原始代码中的一两个功能(我确定你可以在真正需要的时候添加它们),但是对于给定的输入样本它可以正常工作。

哦,如果它不清楚这里发生了什么:我已经对算法进行了矢量化,认识到这些字符对都是独立的,所以NumPy可以用来执行条件运算一次遍历整个字符串,在Python本身没有迭代。

答案 1 :(得分:2)

天真,1对1翻译因为我懒惰而且无聊并且不想继续研究我应该做的事情(C99或更高版本):

#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;
}

构建和输出:

[fbgo448@n9dvap997]~/prototypes/decoder: !g
gcc -o decoder -g -std=c99 -pedantic -Wall -Werror decoder.c
[fbgo448@n9dvap997]~/prototypes/decoder: ./decoder
Encrypted string: 0T1M1L1BtT1L1BtT1TtT1B1T1H1E1I1PtT1B2Z1C1L1G1NtTtNtT2Z1M1T2ZtT2W1PtT1T1C1PtTzutT2Z1P1B2Z1L1G1N
Decrypted string: This is a sample string & that we are = testing