I am attempting to convert a C application to python. I am having difficultiy on this particular for loop. Any ideas how I might proceede?

bool Enigma2C::encrypt(char *inString, char *outString)
{
    int16 csum = 1, checksum = 0;
    int16 tmpSum = 0;
    int16 i = 0;

    strcpy(m_keyCode, inString);

    // Calculate and store 2-digit checksum.
    for (i = 2; i < KEY_LENGTH; i++)
    {
        if (isdigit(m_keyCode[i]))
        {
            tmpSum = m_keyCode[i] - '0';
        }
        else
        {
            tmpSum = m_keyCode[i] - 'A';
        }

        csum += i + tmpSum + (i * tmpSum);
        printf( "DEBUG> csum: %d\n", csum );
    }

    csum = 100 - (csum % 100);
    m_keyCode[0] = '0' + (csum % 10);
    m_keyCode[1] = '0' + ((csum / 10) % 10);
       printf( "DEBUG m_keyCode: %s\n", m_keyCode);

Part of the issue is I need to start the index at posistion 2.

Here is the python for loop so far

csum = 1
    for idx in range(key_length):
        print(idx, key_length)
        tmpsum = (key_length * 2) - 2

        csum += idx + tmpsum + (idx * tmpsum)
        print( "DEBUG> csum:", csum)

If you want to start at position 2, you only need

for idx in range(2, key_length):

Do you have a variable m_keyCode ? The body of the for loop depends on this. If you are with python 3 and m_keyCode is a bytes instance, it is easy because the values are already small integers, for example

>>> v = b'4211'
>>> print([x for x in v])
[52, 50, 49, 49]

If you are with python 2, you'll have to use ord()

>>> v = '4211'
>>> print([ord(x) for x in v])
[52, 50, 49, 49]

Ok thanks, I got the loop starting at position 2 now.

So, I"m also not quite sure how to do that in python.

The C Code shows m_keyCode like this

const int16 KEY_LENGTH = PRODUCT_CODE_SIZE + OPTION_CODE_SIZE
        + SERIAL_NUMBER_SIZE + CHECK_SUM_SIZE;
const int16 SERIAL_LOCATION = CHECK_SUM_SIZE + PRODUCT_CODE_SIZE;
const int16 PRODUCT_LOCATION = CHECK_SUM_SIZE;
const int16 OPTION_LOCATION = CHECK_SUM_SIZE + PRODUCT_CODE_SIZE
        + SERIAL_NUMBER_SIZE;

const int MAX_CHECK_SUM = 26000;

static int16 eRotor10[] =
{ 5, 4, 1, 8, 7, 3, 0, 2, 9, 6 };

static int16 eRotor26[] =
{ 16, 8, 25, 5, 23, 21, 18, 17, 2, 1, 7, 24, 15, 11, 9, 6, 3, 0, 19, 12, 22, 14,
        10, 4, 20, 13, };

static char m_keyCode[KEY_LENGTH];

This where I'm at. Still not quite there.

Confused

    key_length = len(enigma_string)
    m_key_code = [enigma_string]
    print([x for x in m_key_code])

    print("Enigma String: ", enigma_string)
    enigma_py_option = int(enigma_string)

    print("DEBUG Key Length: ", key_length)
    print("DEBUG e_rotor_10: ", e_rotor_10)
    print("DEBUG e_rotor_26: ", e_rotor_26)
    print("DEBUG option code: "), enigma_py_option

    check_sum = 1
    for idx in range(2, key_length):
        if int(key_length):
            temp_sum = key_length - 0
            print("DEBUG temp Sum", temp_sum)
        else:
            temp_sum = key_length - "A"

        check_sum += idx + temp_sum + (idx * temp_sum)
        print("DEBUG> Check Sum:", check_sum)

We still don't know if you are using python 3, nor the type of enigma_string, which is necessary here (print type(enigma_string)). Assuming this is python 3 and enigma_string is a bytes, you can try

    key_length = len(enigma_string)
    m_key_code = enigma_string
    n0, n9, nA = b'09A'


    check_sum = 1
    for idx, n in enumerate(m_key_code[2:], 2):
        if n0 <= n <= n9:
            temp_sum = n - n0
            print("DEBUG temp Sum", temp_sum)
        else:
            temp_sum = n - nA

        check_sum += idx + temp_sum + (idx * temp_sum)
        print("DEBUG> Check Sum:", check_sum)

    check_sum = 100 - (check_sum) % 100
    dummy = [n0 + (check_sum % 10), n0 + ((check_sum // 10) % 10)]
    m_key_code = bytes(dummy) + m_key_code[2:]

Edited 1 Year Ago by Gribouillis

Sorry, I am indeed using python 3 and enimga_string is a <class 'str'>

So I did this
mcode = str.encode(enigma_string)

Now it seems to be working. THANK YOU TANK YOU.

C Code Output: DEBUG m_keyCode: 5470011234567000
When I do the same for the python code I get
Python Code OutPut: DEBUG: m_key_code

Not quite sure why that is.

Final section of code to be converted

MAX_CHECK_SUM = 26000

checksum = 0;
    for (i = 0; i < KEY_LENGTH; i++)
    {

        if (isdigit(m_keyCode[i]))
        {
            tmpSum = m_keyCode[i] - '0';
            m_keyCode[i] = eRotor10[(tmpSum + MAX_CHECK_SUM - checksum) % 10]
                    + '0';
        }
        else
        {
            tmpSum = m_keyCode[i] - 'A';
            m_keyCode[i] = eRotor26[(tmpSum + MAX_CHECK_SUM - checksum) % 26]
                    + 'A';
        }
        checksum += i + tmpSum + (i * tmpSum);
    }

    strcpy(outString, m_keyCode);

Nevermind it is printing out the m_key_code correctly. Its a matter of me writing the debug print statement correctly.

So just the final section of code and I'm done

Ok having another problem :-(

Here is the python3 code

Error Message: m_key_code = bytes(e_rotor_10[(temp_sum + max_check_sum - checksum) % 10] + 0) + m_key_code[:]
TypeError: 'set' object does not support indexing

    # Rotors used to calculate Option Key
    e_rotor_10 = {5, 4, 1, 8, 7, 3, 0, 2, 9, 6}
    e_rotor_26 = {16, 8, 25, 5, 23, 21, 18, 17, 2, 1, 7, 24, 15, 11, 9, 6, 3, 0, 19, 12, 22, 14, 10, 4, 20, 13, }

    # Setting max check sum size to 26000
    max_check_sum = 26000

    print("DEBUG: e_rotor_10: ", e_rotor_10)
    print("DEBUG: e_rotor_26: ", e_rotor_26)

# Encipher Key
    for idx in m_key_code[2:]:
        print(idx)

    checksum = 0
    for idx, n in enumerate(m_key_code[:]):
        if n0 <= n <= n9:
            m_key_code = bytes(e_rotor_10[(temp_sum + max_check_sum - checksum) % 10] + 0) + m_key_code[:]
        else:
            temp_sum = n - nA
            m_key_code = bytes(e_rotor_26[(temp_sum + max_check_sum - checksum) % 26] + nA)

        checksum += idx + temp_sum + (idx * temp_sum)
        print("m_key_code", m_key_code)

Yes {} does not have the same semantics in C or in python. Use lists [] or tuples () for the e_rotor*. Or you can probably use a bytes

e_rotor_10 = bytes([5, 4, 1, 8, 7, 3, 0, 2, 9, 6])

Edited 1 Year Ago by Gribouillis

I'm not sure if this is a byte issue or if my math is off.

Expected Results
DEBUG m_keyCode: 5470011234567000
DEBUG: tmpSum 5
DEBUG: m_key_code 71151984
DEBUG: tmpSum 4
DEBUG: m_key_code 71151984
DEBUG: tmpSum 7
DEBUG: m_key_code 71151984
DEBUG: tmpSum 0
DEBUG: m_key_code 71151984
DEBUG: tmpSum 0
DEBUG: m_key_code 71151984
DEBUG: tmpSum 1
DEBUG: m_key_code 71151984
DEBUG: tmpSum 1
DEBUG: m_key_code 71151984
DEBUG: tmpSum 2
DEBUG: m_key_code 71151984
DEBUG: tmpSum 3
DEBUG: m_key_code 71151984
DEBUG: tmpSum 4
DEBUG: m_key_code 71151984
DEBUG: tmpSum 5
DEBUG: m_key_code 71151984
DEBUG: tmpSum 6
DEBUG: m_key_code 71151984
DEBUG: tmpSum 7
DEBUG: m_key_code 71151984
DEBUG: tmpSum 0
DEBUG: m_key_code 71151984
DEBUG: tmpSum 0
DEBUG: m_key_code 71151984
DEBUG: tmpSum 0
DEBUG: m_key_code 71151984

Results I'm gettting
DEBUG: m_key_code b'5470011234567000'
DEBUG: temp_sum 5
DEBUG: m_key_code 3
DEBUG: temp_sum 4
DEBUG: m_key_code 6
DEBUG: temp_sum 7
DEBUG: m_key_code 8
DEBUG: temp_sum 0
DEBUG: m_key_code 8
DEBUG: temp_sum 0
DEBUG: m_key_code 5
DEBUG: temp_sum 1
DEBUG: m_key_code 2
DEBUG: temp_sum 1
DEBUG: m_key_code 0
DEBUG: temp_sum 2
DEBUG: m_key_code 7
DEBUG: temp_sum 3
DEBUG: m_key_code 1
DEBUG: temp_sum 4
DEBUG: m_key_code 9
DEBUG: temp_sum 5
DEBUG: m_key_code 5
DEBUG: temp_sum 6
DEBUG: m_key_code 0
DEBUG: temp_sum 7
DEBUG: m_key_code 7
DEBUG: temp_sum 0
DEBUG: m_key_code 7
DEBUG: temp_sum 0
DEBUG: m_key_code 4
DEBUG: temp_sum 0
DEBUG: m_key_code 2
m_key_code 2

Code:

Encipher Key

checksum = 0
print("DEBUG: m_key_code",m_key_code)
for idx, n in enumerate(m_key_code[:]):
    if n0 <= n <= n9:
        temp_sum = (n - n0)
        print("DEBUG: temp_sum", temp_sum)
        m_key_code = (e_rotor_10[(temp_sum + max_check_sum - checksum) % 10] + 0)
        print("DEBUG: m_key_code", m_key_code)
    else:
        temp_sum = n - nA
        m_key_code = (e_rotor_26[(temp_sum + max_check_sum - checksum) % 26] + nA)

    checksum += idx + temp_sum + (idx * temp_sum)

print("m_key_code", m_key_code)

Your python code does not look like the C code. At line 7 and 11, it should be m_key_code[idx] = .... Also 0 should probably be n0 at the end of line 7.

It means that m_key_code must be a writable structure such as a list or an array (in module array). What type did you choose for m_key_code ?

Edit: Sorry, I see from the log that m_key_code is a bytes. It won't work because a bytes is immutable.

Edited 1 Year Ago by Gribouillis

Here is what you can do with an array for example

>>> from array import array
>>> spam = b'5470011234567000'
>>> eggs = array('b', spam)
>>> eggs
array('b', [53, 52, 55, 48, 48, 49, 49, 50, 51, 52, 53, 54, 55, 48, 48, 48])
>>> spam
b'5470011234567000'
>>> eggs[3] = 67
>>> eggs
array('b', [53, 52, 55, 67, 48, 49, 49, 50, 51, 52, 53, 54, 55, 48, 48, 48])
>>> bytes(eggs)
b'547C011234567000'

Unless you can guarantee that all characters are in the range of ASCII (32-255), the last line of C code could fail as it could have embedded NULL charcter. It should be memcpy(outstring,instring,ThisManyBytes);
where ThisManyBytes is the number of bytes allowed for outstring.

This question has already been answered. Start a new discussion instead.