您的位置:首页 > 编程语言 > Python开发

【详解】Python统一解密

2015-11-03 18:33 716 查看
我们先贴出原来的解密方式

def getJson(value):
value=value.replace('+', '%2b')
url ="http://localhost:8080/ngtradebackend/goods/getdecodejson.html?value=%s"%value
data = urllib2.urlopen(url).read()
data=json.loads(data)
return data['decode']

调用getJson这个函数。解密时的调用方式为:
f.write(getJson(value[0]).decode('utf-8').encode('gbk')+',')

即,每当有一个密文需要解密时,就去解密。

如果我们有100个密文需要解密,就需要访问解密链接100次,1000个需要解密的,就需要访问解密链接1000次。

不停的访问链接,对web工程的压力是比较大的。

为了减轻对解密后台的压力,我们需要解密时,将需要解密的密文一次性传到后台去,再一次性传回来。

传递的密文用?跟在url后面传递。

如果有100个密文,不可能手写url,这就需要我们利用循环遍历去拼接url这个字符串

url="http://localhost:8080/ngtradebackend/goods/getdecodejson.html?"
for i in range(valuelist0.__len__()):
valuelist0[i]=valuelist0[i].replace('+', '%2b')
valuelist1[i]=valuelist1[i].replace('+', '%2b')
url =url+"value%s=%s&"%(i,valuelist0[i])
url =url+"value%s=%s&"%(i+valuelist0.__len__(),valuelist1[i])
url=url+"len=%s"%(valuelist0.__len__()+valuelist1.__len__())
data = urllib2.urlopen(url).read()
data=json.loads(data)


【+号问题】

注意:我们这里对密文中的+号进行了%2b替换,因为在url传递参数时,+号会被当成空格,所以需要替换。%2b等价于+号。

而且,只能够在Python代码中进行替换,不能等传到了java中再替换,因为+号根本就传递不过去,所以在java中用\\+替代%2b是没有用的,\\+经过了传递已经是空格了。

诶?那是不是能够将空格替换成+号呢?

容易出错,万一有意想不到的空格蹦出来就SB了

言归正传。上述代码块即是我们拼接url字符串的遍历代码。

为了区分密文哪个是哪个,需要为每个参数加编号,

"value%s=%s&"%(i,valuelist0[i])

为了区分明文哪个是哪个,相应的也需要为每个明文加编号,

model.put("decode"+i, decodeValue[i]);


这样在传递密文和接收明文时,就能够把密文和明文对应了。

【明确思路】

知道了拼接url统一传递密文的方法,我们来理一下统一解密的大体思路。

本例中,

拿到一堆符合条件的ID,

用这一堆ID我们可以getInfo,拿到一堆对应的数据库中一行一行的数据,

每一行中,我们只需要找出我们需要解密的那部分就可以,把row[7]拿出来,

拿到xml后,解析,拿到密文,

当然还是一堆密文,把这一堆密文编号,遍历拼接到url字符串中,

url传递过去后,

java的解密代码,根据编号一一解密,

再将一堆加了编号的明文传递回来,

拿到明文后,根据编号,将明文放到该放的地方,写入txt

【明确思想】

整体的思路就是这样,其中,

一堆数据的传递,肯定是要放在数组里方便统一传递的,

而对统一传递过来的一个数组,如果要对其中的某个数据进行处理,肯定要经过遍历,在循环体中一个个处理的,这个思想是一定要有的!

【详解】

我们按整理好的思路一一来进行!!

1.

拿到一堆符合条件的ID,

sql='select ID from SELLING_GOODS where GOODS_ID=887 and SELLING_STATUS=0 and IS_VISIBLE=1 and STATUS=1 and ID not in (select SELLING_GOODS_ID from SELLING_GOODS_PIC) and ID not in (select SELLING_GOODS_ID from SELLING_GOODS_VIDEO_RECORD)'
rows = tradeDBUtil.queryList(sql)

用这一堆ID,来getInfo

2.

放到数组中传递:

arr = []
for row in rows:
arr.append(row[0])
data=getData(arr)


def getData(arr):

ID放到数组中,方便传递到方法中进行处理。

3.

getInfo,而info也是一堆,所以也放在数组里

rowslist=[]
for i in range(arr.__len__()):
rowslist.append(getInfo(arr[i]))

4.

从info中取出row[7],即xml,拿到xml才能在后面解析

for i in range(rowslist.__len__()):
for row in rowslist[i]:
for j in range(row.__len__()):
xml=row[7]

自然是从一堆info数组中进行遍历,一个个取出来的

取出来后,在循环体中直接能拿到value,即密文

soup = BeautifulSoup(xml, "html.parser", from_encoding="gbk")
value = soup.find_all(name="value", attrs={}, text=re.compile("\S"))
value=delValueTag(value)

5.

密文是要遍历加到url中去的,所以需要传递,把这一堆value放到数组中

valuelist0=[]
valuelist1=[]

valuelist0.append(value[0])
valuelist1.append(value[1])

数组的定义是在循环体外的,

往循环体中添加值是在循环体中的,

6.

将密文组成的数组循环遍历,添加到url中

url="http://localhost:8080/ngtradebackend/goods/getdecodejson.html?"
for i in range(valuelist0.__len__()):
valuelist0[i]=valuelist0[i].replace('+', '%2b')
valuelist1[i]=valuelist1[i].replace('+', '%2b')
url =url+"value%s=%s&"%(i,valuelist0[i])
url =url+"value%s=%s&"%(i+valuelist0.__len__(),valuelist1[i])
url=url+"len=%s"%(valuelist0.__len__()+valuelist1.__len__())

添加时,要对每一个密文进行编号,编号肯定是要独一无二的,不能重复

其中的长度参数len是为了在java代码中解密时,进行遍历次数的设定。

7.

url拼接好之后,在解密代码中进行解密

public ModelAndView getDecodeJson(HttpServletRequest request, HttpServletResponse response) throws NgTradeBackendException {
String len=request.getParameter("len");
int length=Integer.parseInt(len);
Map model=new HashMap();
String value[]=new String[length];
String decodeValue[]=new String[length];
for(int i=0;i<length;i++){
value[i]=request.getParameter("value"+i);
decodeValue[i]=value[i];
System.out.println(decodeValue[i]);
try {
if(value[i].startsWith(GOODS_ATTR_KEY_STARTS_WITH_OLD)) {
decodeValue[i]=
new String(des.decrypt((new BASE64Decoder().decodeBuffer(value[i].replace(GOODS_ATTR_KEY_STARTS_WITH_OLD, ""))),
GOODS_ATTR_KEY_OLD.getBytes()), "UTF-8");
} else if(value[i].startsWith(GOODS_ATTR_KEY_STARTS_WITH_NEW)) {
decodeValue[i]=
new String(des.decrypt((new BASE64Decoder().decodeBuffer(value[i].replace(GOODS_ATTR_KEY_STARTS_WITH_NEW, ""))),
GOODS_ATTR_KEY_NEW.getBytes()), "UTF-8");
}
} catch(Exception e) {
e.printStackTrace();
}
System.out.println(decodeValue[i]);
model.put("decode"+i, decodeValue[i]);
}

return new ModelAndView(JSON_VIEW, model);
}
在解密代码中,我们可以看到,解密时,是循环遍历接收的密文,

然后按编号来进行解密的,解密后的明文,在装model时,给明文加上编号。

这样传递回来的model就是很多带编号的decode了,

这些 decodei 对应的就是传递过来的 valuei

8.

接收传递回来的明文

data = urllib2.urlopen(url).read()
data=json.loads(data)
return data

9.

将一堆明文写入txt,先传递到写入的函数那里

data=getData(arr)
for row in rows:
main(row[0], data, arr)


def main(idNumber,data,arr):

writeTxt(idNumber,data,arr)


def writeTxt(idNumber,data,arr):


写入

f.write(name[0].decode('utf-8').encode('gbk')+': ')
f.write(data['decode'+str(index)].decode('utf-8').encode('gbk')+',')
f.write(name[1].decode('utf-8').encode('gbk')+': ')
f.write(data['decode'+str(index+arr.__len__())].decode('utf-8').encode('gbk')+'\n')
f.close()


这里遇到一个问题,如何确定哪个明文属于哪个ID呢?

我们想到一个办法,利用arr的下标,因为最初传递一堆ID时,就是装在arr中传递的

所以通过取arr的下标,可以确定decodei属于哪个ID!

所以,我们才需要传递arr到写入函数中。

这部分属于比较核心的想法!因为decodei中的i怎么和传递过来的idNumber对应是一件比较麻烦的事情,

一个是ID编号,一个是明文编号,不一样!

把arr传过来,我们可以看到,idNumber在arr中的编号,与明文的编号有一定的对应关系。

index=arr.index(idNumber)

实际上,我们是利用arr.index,将idNumber转换为了明文的编号i

至此,统一解密就实现了!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: