在数组初始化中Python中的奇怪行为

时间:2015-07-27 08:56:50

标签: python python-2.7

在下文中,您将看到我编写的用于将APDU命令发送到智能卡的Python程序片段。我在这个程序中使用了PySCard库。

第一个程序:

for LOAD_KEY in validLoadCommands:
    data,sw1,sw2 =connection.transmit(LOAD_KEY)
    temp = LOAD_KEY
    x= temp[3]
    for j in range(0,len(LOAD_KEY)):
        LOAD_KEY[j]=hex(LOAD_KEY[j])
    print '   >>>',' Load Command :',
    for j in range(0,len(LOAD_KEY)):
        LOAD_KEY[j]=str(LOAD_KEY[j])
        if len(LOAD_KEY[j])==3:
            LOAD_KEY[j]=LOAD_KEY[j][0:2]+'0'+LOAD_KEY[j][2]
        print LOAD_KEY[j],
    print
    for j in range(0,len(data)):
        data[j]=hex(data[j])
    print '   <<<',' Data :',
    for j in range(0,len(data)):
        data[j]=str(data[j])
        if len(data[j])==3:
            data[j]=data[j][0:2]+'0'+data[j][2]
        print data[j],
    print '--',hex(sw1),hex(sw2)

    if (temp[2] == 0x00 or temp[2] == 0x20):
        keyType = 0x60
    else:
        keyType = 0x61

    AUTH = [0xFF, 0x86, 0x00, 0x00, 0x05, 0x01, 0x00, blockNum, keyType,temp[3]]
    print 'AUTH Command: ', AUTH
    data,sw1,sw2 =connection.transmit(AUTH)
    print data, sw1, sw2

及其输出:

Auth Command: [255, 134, 0, 0, 5, 1, 0, 4, 97, '0x0e']

Traceback (most recent call last):
  File "C:\Users\Erb4h1m\Desktop\Faraadis Alborz Card Reader\CRT-603-CZ1_Read1Block.py", line 199, in <module>
    data,sw1,sw2 =connection.transmit(AUTH)
  File "D:\Software\Python27\lib\site-packages\smartcard\CardConnectionDecorator.py", line 82, in transmit
    return self.component.transmit(bytes, protocol)
  File "D:\Software\Python27\lib\site-packages\smartcard\CardConnection.py", line 140, in transmit
    data, sw1, sw2 = self.doTransmit(bytes, protocol)
  File "D:\Software\Python27\lib\site-packages\smartcard\pcsc\PCSCCardConnection.py", line 173, in doTransmit
    hresult, response = SCardTransmit(self.hcard, pcscprotocolheader, bytes)
  File "D:\Software\Python27\lib\site-packages\smartcard\scard\scard.py", line 1329, in SCardTransmit
    return _scard.SCardTransmit(*args)
TypeError: Expected a list of bytes.

当我用temp[3]替换x时:

for LOAD_KEY in validLoadCommands:
    data,sw1,sw2 =connection.transmit(LOAD_KEY)
    temp = LOAD_KEY
    x= temp[3]
    for j in range(0,len(LOAD_KEY)):
        LOAD_KEY[j]=hex(LOAD_KEY[j])
    print '   >>>',' Load Command :',
    for j in range(0,len(LOAD_KEY)):
        LOAD_KEY[j]=str(LOAD_KEY[j])
        if len(LOAD_KEY[j])==3:
            LOAD_KEY[j]=LOAD_KEY[j][0:2]+'0'+LOAD_KEY[j][2]
        print LOAD_KEY[j],
    print
    for j in range(0,len(data)):
        data[j]=hex(data[j])
    print '   <<<',' Data :',
    for j in range(0,len(data)):
        data[j]=str(data[j])
        if len(data[j])==3:
            data[j]=data[j][0:2]+'0'+data[j][2]
        print data[j],
    print '--',hex(sw1),hex(sw2)

    if (temp[2] == 0x00 or temp[2] == 0x20):
        keyType = 0x60
    else:
        keyType = 0x61

    AUTH = [0xFF, 0x86, 0x00, 0x00, 0x05, 0x01, 0x00, blockNum, keyType, x]
    print 'AUTH Command: ', AUTH
    data,sw1,sw2 =connection.transmit(AUTH)
    print data, sw1, sw2

然后输出是:

AUTH: [255, 134, 0, 0, 5, 1, 0, 4, 97, 14]
[] 144 0

如上所述,在第二种情况下,我不会收到任何错误,而第一个程序和第二个程序之间没有区别!我只换了

    AUTH = [0xFF, 0x86, 0x00, 0x00, 0x05, 0x01, 0x00, blockNum, keyType,temp[3]]

使用:

    AUTH = [0xFF, 0x86, 0x00, 0x00, 0x05, 0x01, 0x00, blockNum, keyType,x]

x在程序顶部初始化为temp[3]。 {/ 1}}和x在初始化线和错误线之间都没有变化。

这是怎么回事?

2 个答案:

答案 0 :(得分:2)

您的temp变量引用LOAD_KEY(第3行:temp = LOAD_KEY

x= temp[3]被调用时,它就是LOAD_KEY设置后的索引3处connection.transmit的值。

当您为temp[3]发送AUTH时,LOAD_KEY已更改temp[3]。所以它不再是x的相同值。

connection.transmit => LOAD_KEY is set => temp => [3] => x
*** LOAD_KEY changes ***
x => old value of temp[3] aka LOAD_KEY[3]
temp[3] => whatever your code have put in it

编辑:简短的例子

>>> LOAD_KEY = ['one', 'two', 'three', 'four']
>>> temp = LOAD_KEY
>>> x = temp[3]
>>> LOAD_KEY[3] = 'new value'
>>>
>>> LOAD_KEY[3]
'new value'
>>> temp[3]
'new value'
>>> x
'four'

答案 1 :(得分:2)

在第一个示例中,temp[3]是一个字符串('0x0e')。

在第二个示例中,x是一个整数(14)。

这是因为您将LOAD_KEY列表的整数值转换为十六进制字符串,其中包含以下行:

LOAD_KEY[j] = hex(LOAD_KEY[j])

为了将十六进制表示形式的字符串转换为整数,请使用内置类型int的第二个参数将基数设置为16:

>>> int('0x0e', 16)
14