1############################################################################### 2## 3## Copyright (C) 2012-2013 Tavendo GmbH 4## 5## Licensed under the Apache License, Version 2.0 (the "License"); 6## you may not use this file except in compliance with the License. 7## You may obtain a copy of the License at 8## 9## http://www.apache.org/licenses/LICENSE-2.0 10## 11## Unless required by applicable law or agreed to in writing, software 12## distributed under the License is distributed on an "AS IS" BASIS, 13## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14## See the License for the specific language governing permissions and 15## limitations under the License. 16## 17############################################################################### 18 19import six 20 21 22## use Cython implementation of XorMasker validator if available 23## 24try: 25 from wsaccel.xormask import XorMaskerNull, createXorMasker 26 27except: 28 ## fallback to pure Python implementation 29 30 ## http://stackoverflow.com/questions/15014310/python3-xrange-lack-hurts 31 try: 32 xrange 33 except NameError: 34 ## Python 3 35 xrange = range 36 37 from array import array 38 39 class XorMaskerNull: 40 41 # noinspection PyUnusedLocal 42 def __init__(self, mask = None): 43 self.ptr = 0 44 45 def pointer(self): 46 return self.ptr 47 48 def reset(self): 49 self.ptr = 0 50 51 def process(self, data): 52 self.ptr += len(data) 53 return data 54 55 56 class XorMaskerSimple: 57 58 def __init__(self, mask): 59 assert len(mask) == 4 60 self.ptr = 0 61 self.msk = array('B', mask) 62 63 def pointer(self): 64 return self.ptr 65 66 def reset(self): 67 self.ptr = 0 68 69 def process(self, data): 70 dlen = len(data) 71 payload = array('B', data) 72 for k in xrange(dlen): 73 payload[k] ^= self.msk[self.ptr & 3] 74 self.ptr += 1 75 return payload.tostring() 76 77 78 class XorMaskerShifted1: 79 80 def __init__(self, mask): 81 assert len(mask) == 4 82 self.ptr = 0 83 self.mskarray = [array('B'), array('B'), array('B'), array('B')] 84 if six.PY3: 85 for j in xrange(4): 86 self.mskarray[0].append(mask[ j & 3]) 87 self.mskarray[1].append(mask[(j + 1) & 3]) 88 self.mskarray[2].append(mask[(j + 2) & 3]) 89 self.mskarray[3].append(mask[(j + 3) & 3]) 90 else: 91 for j in xrange(4): 92 self.mskarray[0].append(ord(mask[ j & 3])) 93 self.mskarray[1].append(ord(mask[(j + 1) & 3])) 94 self.mskarray[2].append(ord(mask[(j + 2) & 3])) 95 self.mskarray[3].append(ord(mask[(j + 3) & 3])) 96 97 def pointer(self): 98 return self.ptr 99 100 def reset(self): 101 self.ptr = 0 102 103 def process(self, data): 104 dlen = len(data) 105 payload = array('B', data) 106 msk = self.mskarray[self.ptr & 3] 107 for k in xrange(dlen): 108 payload[k] ^= msk[k & 3] 109 self.ptr += dlen 110 return payload.tostring() 111 112 113 def createXorMasker(mask, len = None): 114 if len is None or len < 128: 115 return XorMaskerSimple(mask) 116 else: 117 return XorMaskerShifted1(mask) 118