Simplified DES encryption
$begingroup$
This is one of my first Python scripts and I was wondering if it meets the correct conventions. Also are there things that you would write different? I am looking for some good comments so I can start to improve my Python code from the start. (I was not supposed to use imports here)
Here's my implementation of Simplified DES:
__author__ = 'ßaron'
FIXED_IP = [2, 6, 3, 1, 4, 8, 5, 7]
FIXED_EP = [4, 1, 2, 3, 2, 3, 4, 1]
FIXED_IP_INVERSE = [4, 1, 3, 5, 7, 2, 8, 6]
FIXED_P10 = [3, 5, 2, 7, 4, 10, 1, 9, 8, 6]
FIXED_P8 = [6, 3, 7, 4, 8, 5, 10, 9]
FIXED_P4 = [2, 4, 3, 1]
S0 = [[1, 0, 3, 2],
[3, 2, 1, 0],
[0, 2, 1, 3],
[3, 1, 3, 2]]
S1 = [[0, 1, 2, 3],
[2, 0, 1, 3],
[3, 0, 1, 0],
[2, 1, 0, 3]]
KEY = '0111111101'
def permutate(original, fixed_key):
new = ''
for i in fixed_key:
new += original[i - 1]
return new
def left_half(bits):
return bits[:len(bits)/2]
def right_half(bits):
return bits[len(bits)/2:]
def shift(bits):
rotated_left_half = left_half(bits)[1:] + left_half(bits)[0]
rotated_right_half = right_half(bits)[1:] + right_half(bits)[0]
return rotated_left_half + rotated_right_half
def key1():
return permutate(shift(permutate(KEY, FIXED_P10)), FIXED_P8)
def key2():
return permutate(shift(shift(shift(permutate(KEY, FIXED_P10)))), FIXED_P8)
def xor(bits, key):
new = ''
for bit, key_bit in zip(bits, key):
new += str(((int(bit) + int(key_bit)) % 2))
return new
def lookup_in_sbox(bits, sbox):
row = int(bits[0] + bits[3], 2)
col = int(bits[1] + bits[2], 2)
return '{0:02b}'.format(sbox[row][col])
def f_k(bits, key):
L = left_half(bits)
R = right_half(bits)
bits = permutate(R, FIXED_EP)
bits = xor(bits, key)
bits = lookup_in_sbox(left_half(bits), S0) + lookup_in_sbox(right_half(bits), S1)
bits = permutate(bits, FIXED_P4)
return xor(bits, L)
def encrypt(plain_text):
bits = permutate(plain_text, FIXED_IP)
temp = f_k(bits, key1())
bits = right_half(bits) + temp
bits = f_k(bits, key2())
print permutate(bits + temp, FIXED_IP_INVERSE)
def decrypt(cipher_text):
bits = permutate(cipher_text, FIXED_IP)
temp = f_k(bits, key2())
bits = right_half(bits) + temp
bits = f_k(bits, key1())
print permutate(bits + temp, FIXED_IP_INVERSE)
encrypt('11101010')
decrypt('10100010')
python beginner reinventing-the-wheel cryptography
$endgroup$
|
show 2 more comments
$begingroup$
This is one of my first Python scripts and I was wondering if it meets the correct conventions. Also are there things that you would write different? I am looking for some good comments so I can start to improve my Python code from the start. (I was not supposed to use imports here)
Here's my implementation of Simplified DES:
__author__ = 'ßaron'
FIXED_IP = [2, 6, 3, 1, 4, 8, 5, 7]
FIXED_EP = [4, 1, 2, 3, 2, 3, 4, 1]
FIXED_IP_INVERSE = [4, 1, 3, 5, 7, 2, 8, 6]
FIXED_P10 = [3, 5, 2, 7, 4, 10, 1, 9, 8, 6]
FIXED_P8 = [6, 3, 7, 4, 8, 5, 10, 9]
FIXED_P4 = [2, 4, 3, 1]
S0 = [[1, 0, 3, 2],
[3, 2, 1, 0],
[0, 2, 1, 3],
[3, 1, 3, 2]]
S1 = [[0, 1, 2, 3],
[2, 0, 1, 3],
[3, 0, 1, 0],
[2, 1, 0, 3]]
KEY = '0111111101'
def permutate(original, fixed_key):
new = ''
for i in fixed_key:
new += original[i - 1]
return new
def left_half(bits):
return bits[:len(bits)/2]
def right_half(bits):
return bits[len(bits)/2:]
def shift(bits):
rotated_left_half = left_half(bits)[1:] + left_half(bits)[0]
rotated_right_half = right_half(bits)[1:] + right_half(bits)[0]
return rotated_left_half + rotated_right_half
def key1():
return permutate(shift(permutate(KEY, FIXED_P10)), FIXED_P8)
def key2():
return permutate(shift(shift(shift(permutate(KEY, FIXED_P10)))), FIXED_P8)
def xor(bits, key):
new = ''
for bit, key_bit in zip(bits, key):
new += str(((int(bit) + int(key_bit)) % 2))
return new
def lookup_in_sbox(bits, sbox):
row = int(bits[0] + bits[3], 2)
col = int(bits[1] + bits[2], 2)
return '{0:02b}'.format(sbox[row][col])
def f_k(bits, key):
L = left_half(bits)
R = right_half(bits)
bits = permutate(R, FIXED_EP)
bits = xor(bits, key)
bits = lookup_in_sbox(left_half(bits), S0) + lookup_in_sbox(right_half(bits), S1)
bits = permutate(bits, FIXED_P4)
return xor(bits, L)
def encrypt(plain_text):
bits = permutate(plain_text, FIXED_IP)
temp = f_k(bits, key1())
bits = right_half(bits) + temp
bits = f_k(bits, key2())
print permutate(bits + temp, FIXED_IP_INVERSE)
def decrypt(cipher_text):
bits = permutate(cipher_text, FIXED_IP)
temp = f_k(bits, key2())
bits = right_half(bits) + temp
bits = f_k(bits, key1())
print permutate(bits + temp, FIXED_IP_INVERSE)
encrypt('11101010')
decrypt('10100010')
python beginner reinventing-the-wheel cryptography
$endgroup$
$begingroup$
Is doing this object-oriented allowed?
$endgroup$
– Mast
Oct 19 '15 at 19:24
$begingroup$
Yes, it is allowed.
$endgroup$
– ßaron
Oct 19 '15 at 19:25
$begingroup$
What is "Simplified DES"? Is it the algorithm described here?
$endgroup$
– Gareth Rees
Oct 19 '15 at 19:25
$begingroup$
Hello @Gareth Rees, that is indeed the algorithm, i should have given the link..
$endgroup$
– ßaron
Oct 19 '15 at 19:27
1
$begingroup$
@ßaron It affects the speed here is the main reason I asked, the more recent you're using the less of a difference Caridorc's answer makes. Also to reply to people in comments make sure you @ them as people don't always got notified otherwise!
$endgroup$
– SuperBiasedMan
Oct 20 '15 at 12:47
|
show 2 more comments
$begingroup$
This is one of my first Python scripts and I was wondering if it meets the correct conventions. Also are there things that you would write different? I am looking for some good comments so I can start to improve my Python code from the start. (I was not supposed to use imports here)
Here's my implementation of Simplified DES:
__author__ = 'ßaron'
FIXED_IP = [2, 6, 3, 1, 4, 8, 5, 7]
FIXED_EP = [4, 1, 2, 3, 2, 3, 4, 1]
FIXED_IP_INVERSE = [4, 1, 3, 5, 7, 2, 8, 6]
FIXED_P10 = [3, 5, 2, 7, 4, 10, 1, 9, 8, 6]
FIXED_P8 = [6, 3, 7, 4, 8, 5, 10, 9]
FIXED_P4 = [2, 4, 3, 1]
S0 = [[1, 0, 3, 2],
[3, 2, 1, 0],
[0, 2, 1, 3],
[3, 1, 3, 2]]
S1 = [[0, 1, 2, 3],
[2, 0, 1, 3],
[3, 0, 1, 0],
[2, 1, 0, 3]]
KEY = '0111111101'
def permutate(original, fixed_key):
new = ''
for i in fixed_key:
new += original[i - 1]
return new
def left_half(bits):
return bits[:len(bits)/2]
def right_half(bits):
return bits[len(bits)/2:]
def shift(bits):
rotated_left_half = left_half(bits)[1:] + left_half(bits)[0]
rotated_right_half = right_half(bits)[1:] + right_half(bits)[0]
return rotated_left_half + rotated_right_half
def key1():
return permutate(shift(permutate(KEY, FIXED_P10)), FIXED_P8)
def key2():
return permutate(shift(shift(shift(permutate(KEY, FIXED_P10)))), FIXED_P8)
def xor(bits, key):
new = ''
for bit, key_bit in zip(bits, key):
new += str(((int(bit) + int(key_bit)) % 2))
return new
def lookup_in_sbox(bits, sbox):
row = int(bits[0] + bits[3], 2)
col = int(bits[1] + bits[2], 2)
return '{0:02b}'.format(sbox[row][col])
def f_k(bits, key):
L = left_half(bits)
R = right_half(bits)
bits = permutate(R, FIXED_EP)
bits = xor(bits, key)
bits = lookup_in_sbox(left_half(bits), S0) + lookup_in_sbox(right_half(bits), S1)
bits = permutate(bits, FIXED_P4)
return xor(bits, L)
def encrypt(plain_text):
bits = permutate(plain_text, FIXED_IP)
temp = f_k(bits, key1())
bits = right_half(bits) + temp
bits = f_k(bits, key2())
print permutate(bits + temp, FIXED_IP_INVERSE)
def decrypt(cipher_text):
bits = permutate(cipher_text, FIXED_IP)
temp = f_k(bits, key2())
bits = right_half(bits) + temp
bits = f_k(bits, key1())
print permutate(bits + temp, FIXED_IP_INVERSE)
encrypt('11101010')
decrypt('10100010')
python beginner reinventing-the-wheel cryptography
$endgroup$
This is one of my first Python scripts and I was wondering if it meets the correct conventions. Also are there things that you would write different? I am looking for some good comments so I can start to improve my Python code from the start. (I was not supposed to use imports here)
Here's my implementation of Simplified DES:
__author__ = 'ßaron'
FIXED_IP = [2, 6, 3, 1, 4, 8, 5, 7]
FIXED_EP = [4, 1, 2, 3, 2, 3, 4, 1]
FIXED_IP_INVERSE = [4, 1, 3, 5, 7, 2, 8, 6]
FIXED_P10 = [3, 5, 2, 7, 4, 10, 1, 9, 8, 6]
FIXED_P8 = [6, 3, 7, 4, 8, 5, 10, 9]
FIXED_P4 = [2, 4, 3, 1]
S0 = [[1, 0, 3, 2],
[3, 2, 1, 0],
[0, 2, 1, 3],
[3, 1, 3, 2]]
S1 = [[0, 1, 2, 3],
[2, 0, 1, 3],
[3, 0, 1, 0],
[2, 1, 0, 3]]
KEY = '0111111101'
def permutate(original, fixed_key):
new = ''
for i in fixed_key:
new += original[i - 1]
return new
def left_half(bits):
return bits[:len(bits)/2]
def right_half(bits):
return bits[len(bits)/2:]
def shift(bits):
rotated_left_half = left_half(bits)[1:] + left_half(bits)[0]
rotated_right_half = right_half(bits)[1:] + right_half(bits)[0]
return rotated_left_half + rotated_right_half
def key1():
return permutate(shift(permutate(KEY, FIXED_P10)), FIXED_P8)
def key2():
return permutate(shift(shift(shift(permutate(KEY, FIXED_P10)))), FIXED_P8)
def xor(bits, key):
new = ''
for bit, key_bit in zip(bits, key):
new += str(((int(bit) + int(key_bit)) % 2))
return new
def lookup_in_sbox(bits, sbox):
row = int(bits[0] + bits[3], 2)
col = int(bits[1] + bits[2], 2)
return '{0:02b}'.format(sbox[row][col])
def f_k(bits, key):
L = left_half(bits)
R = right_half(bits)
bits = permutate(R, FIXED_EP)
bits = xor(bits, key)
bits = lookup_in_sbox(left_half(bits), S0) + lookup_in_sbox(right_half(bits), S1)
bits = permutate(bits, FIXED_P4)
return xor(bits, L)
def encrypt(plain_text):
bits = permutate(plain_text, FIXED_IP)
temp = f_k(bits, key1())
bits = right_half(bits) + temp
bits = f_k(bits, key2())
print permutate(bits + temp, FIXED_IP_INVERSE)
def decrypt(cipher_text):
bits = permutate(cipher_text, FIXED_IP)
temp = f_k(bits, key2())
bits = right_half(bits) + temp
bits = f_k(bits, key1())
print permutate(bits + temp, FIXED_IP_INVERSE)
encrypt('11101010')
decrypt('10100010')
python beginner reinventing-the-wheel cryptography
python beginner reinventing-the-wheel cryptography
edited Oct 20 '15 at 5:56
ßaron
asked Oct 19 '15 at 19:15
ßaronßaron
4516
4516
$begingroup$
Is doing this object-oriented allowed?
$endgroup$
– Mast
Oct 19 '15 at 19:24
$begingroup$
Yes, it is allowed.
$endgroup$
– ßaron
Oct 19 '15 at 19:25
$begingroup$
What is "Simplified DES"? Is it the algorithm described here?
$endgroup$
– Gareth Rees
Oct 19 '15 at 19:25
$begingroup$
Hello @Gareth Rees, that is indeed the algorithm, i should have given the link..
$endgroup$
– ßaron
Oct 19 '15 at 19:27
1
$begingroup$
@ßaron It affects the speed here is the main reason I asked, the more recent you're using the less of a difference Caridorc's answer makes. Also to reply to people in comments make sure you @ them as people don't always got notified otherwise!
$endgroup$
– SuperBiasedMan
Oct 20 '15 at 12:47
|
show 2 more comments
$begingroup$
Is doing this object-oriented allowed?
$endgroup$
– Mast
Oct 19 '15 at 19:24
$begingroup$
Yes, it is allowed.
$endgroup$
– ßaron
Oct 19 '15 at 19:25
$begingroup$
What is "Simplified DES"? Is it the algorithm described here?
$endgroup$
– Gareth Rees
Oct 19 '15 at 19:25
$begingroup$
Hello @Gareth Rees, that is indeed the algorithm, i should have given the link..
$endgroup$
– ßaron
Oct 19 '15 at 19:27
1
$begingroup$
@ßaron It affects the speed here is the main reason I asked, the more recent you're using the less of a difference Caridorc's answer makes. Also to reply to people in comments make sure you @ them as people don't always got notified otherwise!
$endgroup$
– SuperBiasedMan
Oct 20 '15 at 12:47
$begingroup$
Is doing this object-oriented allowed?
$endgroup$
– Mast
Oct 19 '15 at 19:24
$begingroup$
Is doing this object-oriented allowed?
$endgroup$
– Mast
Oct 19 '15 at 19:24
$begingroup$
Yes, it is allowed.
$endgroup$
– ßaron
Oct 19 '15 at 19:25
$begingroup$
Yes, it is allowed.
$endgroup$
– ßaron
Oct 19 '15 at 19:25
$begingroup$
What is "Simplified DES"? Is it the algorithm described here?
$endgroup$
– Gareth Rees
Oct 19 '15 at 19:25
$begingroup$
What is "Simplified DES"? Is it the algorithm described here?
$endgroup$
– Gareth Rees
Oct 19 '15 at 19:25
$begingroup$
Hello @Gareth Rees, that is indeed the algorithm, i should have given the link..
$endgroup$
– ßaron
Oct 19 '15 at 19:27
$begingroup$
Hello @Gareth Rees, that is indeed the algorithm, i should have given the link..
$endgroup$
– ßaron
Oct 19 '15 at 19:27
1
1
$begingroup$
@ßaron It affects the speed here is the main reason I asked, the more recent you're using the less of a difference Caridorc's answer makes. Also to reply to people in comments make sure you @ them as people don't always got notified otherwise!
$endgroup$
– SuperBiasedMan
Oct 20 '15 at 12:47
$begingroup$
@ßaron It affects the speed here is the main reason I asked, the more recent you're using the less of a difference Caridorc's answer makes. Also to reply to people in comments make sure you @ them as people don't always got notified otherwise!
$endgroup$
– SuperBiasedMan
Oct 20 '15 at 12:47
|
show 2 more comments
3 Answers
3
active
oldest
votes
$begingroup$
If you're using constants that are collections you'd be better off making them tuples, not lists. Trying to modify a tuple will raise an error as they're immutable, and using the tuple syntax makes it extra clear that these are unchanging constants.
FIXED_IP = (2, 6, 3, 1, 4, 8, 5, 7)
FIXED_EP = (4, 1, 2, 3, 2, 3, 4, 1)
As Caridorc said, using str.join
is faster (depending on your version). It would also allow you to make permutate
just one line.
def permutate(original, fixed_key):
return ''.join(original[i - 1] for i in fixed_key)
It would also be a bit faster to pre-convert all your values in bits
and key
to integers. You can use map
to apply a function to every member of a list, and it's faster than doing it in a list. You could do this when creating the zip
object.
def xor(bits, key):
new = ''
for bit, key_bit in zip(map(int, bits), map(int, key)):
new += str(((bit + key_bit) % 2))
return new
Of course if you wanted this could also be made into a str.join
, albeit a long one:
def xor(bits, key):
return ''.join(str(((bit + key_bit) % 2)) for bit, key_bit in
zip(map(int, bits), map(int, key)))
There's a lot of functions here but not a lot of documentation. Explaining what individual functions do would make your code a lot easier to read. And I suspect you have some unnecessary duplicate functions, where you could pass a parameter instead of defining a whole new one. But it's hard to know when I don't entirely understand the functions you have here.
$endgroup$
add a comment |
$begingroup$
It is well written overall, but remember that string += thing
is very slow when used in loops and you should join
a generator expression for efficiency.
$endgroup$
$begingroup$
In modern versions of CPython repeated string concatenation is usually only a little slower than join, so this is now only a worry if you want to be portable to other versions of Python like PyPy.
$endgroup$
– Gareth Rees
Oct 19 '15 at 21:09
$begingroup$
@GarethRees just tested, in my Cython 3.4 joining is actually slower (by 20%) but in pypy+=
is so slow as to be totally unusable (more than 100x the time of join and still running)
$endgroup$
– Caridorc
Oct 19 '15 at 21:31
$begingroup$
That's right, so I think that when you give the advice not to use string concatenation you should mention that the advice might not make any difference in CPython, but is still a good idea if you are concerned about portability.
$endgroup$
– Gareth Rees
Oct 20 '15 at 11:31
add a comment |
$begingroup$
Dhaval Tandale - Cognizant 3.38
New contributor
$endgroup$
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
return StackExchange.using("mathjaxEditing", function () {
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
});
});
}, "mathjax-editing");
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "196"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f108057%2fsimplified-des-encryption%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
$begingroup$
If you're using constants that are collections you'd be better off making them tuples, not lists. Trying to modify a tuple will raise an error as they're immutable, and using the tuple syntax makes it extra clear that these are unchanging constants.
FIXED_IP = (2, 6, 3, 1, 4, 8, 5, 7)
FIXED_EP = (4, 1, 2, 3, 2, 3, 4, 1)
As Caridorc said, using str.join
is faster (depending on your version). It would also allow you to make permutate
just one line.
def permutate(original, fixed_key):
return ''.join(original[i - 1] for i in fixed_key)
It would also be a bit faster to pre-convert all your values in bits
and key
to integers. You can use map
to apply a function to every member of a list, and it's faster than doing it in a list. You could do this when creating the zip
object.
def xor(bits, key):
new = ''
for bit, key_bit in zip(map(int, bits), map(int, key)):
new += str(((bit + key_bit) % 2))
return new
Of course if you wanted this could also be made into a str.join
, albeit a long one:
def xor(bits, key):
return ''.join(str(((bit + key_bit) % 2)) for bit, key_bit in
zip(map(int, bits), map(int, key)))
There's a lot of functions here but not a lot of documentation. Explaining what individual functions do would make your code a lot easier to read. And I suspect you have some unnecessary duplicate functions, where you could pass a parameter instead of defining a whole new one. But it's hard to know when I don't entirely understand the functions you have here.
$endgroup$
add a comment |
$begingroup$
If you're using constants that are collections you'd be better off making them tuples, not lists. Trying to modify a tuple will raise an error as they're immutable, and using the tuple syntax makes it extra clear that these are unchanging constants.
FIXED_IP = (2, 6, 3, 1, 4, 8, 5, 7)
FIXED_EP = (4, 1, 2, 3, 2, 3, 4, 1)
As Caridorc said, using str.join
is faster (depending on your version). It would also allow you to make permutate
just one line.
def permutate(original, fixed_key):
return ''.join(original[i - 1] for i in fixed_key)
It would also be a bit faster to pre-convert all your values in bits
and key
to integers. You can use map
to apply a function to every member of a list, and it's faster than doing it in a list. You could do this when creating the zip
object.
def xor(bits, key):
new = ''
for bit, key_bit in zip(map(int, bits), map(int, key)):
new += str(((bit + key_bit) % 2))
return new
Of course if you wanted this could also be made into a str.join
, albeit a long one:
def xor(bits, key):
return ''.join(str(((bit + key_bit) % 2)) for bit, key_bit in
zip(map(int, bits), map(int, key)))
There's a lot of functions here but not a lot of documentation. Explaining what individual functions do would make your code a lot easier to read. And I suspect you have some unnecessary duplicate functions, where you could pass a parameter instead of defining a whole new one. But it's hard to know when I don't entirely understand the functions you have here.
$endgroup$
add a comment |
$begingroup$
If you're using constants that are collections you'd be better off making them tuples, not lists. Trying to modify a tuple will raise an error as they're immutable, and using the tuple syntax makes it extra clear that these are unchanging constants.
FIXED_IP = (2, 6, 3, 1, 4, 8, 5, 7)
FIXED_EP = (4, 1, 2, 3, 2, 3, 4, 1)
As Caridorc said, using str.join
is faster (depending on your version). It would also allow you to make permutate
just one line.
def permutate(original, fixed_key):
return ''.join(original[i - 1] for i in fixed_key)
It would also be a bit faster to pre-convert all your values in bits
and key
to integers. You can use map
to apply a function to every member of a list, and it's faster than doing it in a list. You could do this when creating the zip
object.
def xor(bits, key):
new = ''
for bit, key_bit in zip(map(int, bits), map(int, key)):
new += str(((bit + key_bit) % 2))
return new
Of course if you wanted this could also be made into a str.join
, albeit a long one:
def xor(bits, key):
return ''.join(str(((bit + key_bit) % 2)) for bit, key_bit in
zip(map(int, bits), map(int, key)))
There's a lot of functions here but not a lot of documentation. Explaining what individual functions do would make your code a lot easier to read. And I suspect you have some unnecessary duplicate functions, where you could pass a parameter instead of defining a whole new one. But it's hard to know when I don't entirely understand the functions you have here.
$endgroup$
If you're using constants that are collections you'd be better off making them tuples, not lists. Trying to modify a tuple will raise an error as they're immutable, and using the tuple syntax makes it extra clear that these are unchanging constants.
FIXED_IP = (2, 6, 3, 1, 4, 8, 5, 7)
FIXED_EP = (4, 1, 2, 3, 2, 3, 4, 1)
As Caridorc said, using str.join
is faster (depending on your version). It would also allow you to make permutate
just one line.
def permutate(original, fixed_key):
return ''.join(original[i - 1] for i in fixed_key)
It would also be a bit faster to pre-convert all your values in bits
and key
to integers. You can use map
to apply a function to every member of a list, and it's faster than doing it in a list. You could do this when creating the zip
object.
def xor(bits, key):
new = ''
for bit, key_bit in zip(map(int, bits), map(int, key)):
new += str(((bit + key_bit) % 2))
return new
Of course if you wanted this could also be made into a str.join
, albeit a long one:
def xor(bits, key):
return ''.join(str(((bit + key_bit) % 2)) for bit, key_bit in
zip(map(int, bits), map(int, key)))
There's a lot of functions here but not a lot of documentation. Explaining what individual functions do would make your code a lot easier to read. And I suspect you have some unnecessary duplicate functions, where you could pass a parameter instead of defining a whole new one. But it's hard to know when I don't entirely understand the functions you have here.
answered Oct 20 '15 at 10:47
SuperBiasedManSuperBiasedMan
11.8k52660
11.8k52660
add a comment |
add a comment |
$begingroup$
It is well written overall, but remember that string += thing
is very slow when used in loops and you should join
a generator expression for efficiency.
$endgroup$
$begingroup$
In modern versions of CPython repeated string concatenation is usually only a little slower than join, so this is now only a worry if you want to be portable to other versions of Python like PyPy.
$endgroup$
– Gareth Rees
Oct 19 '15 at 21:09
$begingroup$
@GarethRees just tested, in my Cython 3.4 joining is actually slower (by 20%) but in pypy+=
is so slow as to be totally unusable (more than 100x the time of join and still running)
$endgroup$
– Caridorc
Oct 19 '15 at 21:31
$begingroup$
That's right, so I think that when you give the advice not to use string concatenation you should mention that the advice might not make any difference in CPython, but is still a good idea if you are concerned about portability.
$endgroup$
– Gareth Rees
Oct 20 '15 at 11:31
add a comment |
$begingroup$
It is well written overall, but remember that string += thing
is very slow when used in loops and you should join
a generator expression for efficiency.
$endgroup$
$begingroup$
In modern versions of CPython repeated string concatenation is usually only a little slower than join, so this is now only a worry if you want to be portable to other versions of Python like PyPy.
$endgroup$
– Gareth Rees
Oct 19 '15 at 21:09
$begingroup$
@GarethRees just tested, in my Cython 3.4 joining is actually slower (by 20%) but in pypy+=
is so slow as to be totally unusable (more than 100x the time of join and still running)
$endgroup$
– Caridorc
Oct 19 '15 at 21:31
$begingroup$
That's right, so I think that when you give the advice not to use string concatenation you should mention that the advice might not make any difference in CPython, but is still a good idea if you are concerned about portability.
$endgroup$
– Gareth Rees
Oct 20 '15 at 11:31
add a comment |
$begingroup$
It is well written overall, but remember that string += thing
is very slow when used in loops and you should join
a generator expression for efficiency.
$endgroup$
It is well written overall, but remember that string += thing
is very slow when used in loops and you should join
a generator expression for efficiency.
answered Oct 19 '15 at 20:33
CaridorcCaridorc
23k538116
23k538116
$begingroup$
In modern versions of CPython repeated string concatenation is usually only a little slower than join, so this is now only a worry if you want to be portable to other versions of Python like PyPy.
$endgroup$
– Gareth Rees
Oct 19 '15 at 21:09
$begingroup$
@GarethRees just tested, in my Cython 3.4 joining is actually slower (by 20%) but in pypy+=
is so slow as to be totally unusable (more than 100x the time of join and still running)
$endgroup$
– Caridorc
Oct 19 '15 at 21:31
$begingroup$
That's right, so I think that when you give the advice not to use string concatenation you should mention that the advice might not make any difference in CPython, but is still a good idea if you are concerned about portability.
$endgroup$
– Gareth Rees
Oct 20 '15 at 11:31
add a comment |
$begingroup$
In modern versions of CPython repeated string concatenation is usually only a little slower than join, so this is now only a worry if you want to be portable to other versions of Python like PyPy.
$endgroup$
– Gareth Rees
Oct 19 '15 at 21:09
$begingroup$
@GarethRees just tested, in my Cython 3.4 joining is actually slower (by 20%) but in pypy+=
is so slow as to be totally unusable (more than 100x the time of join and still running)
$endgroup$
– Caridorc
Oct 19 '15 at 21:31
$begingroup$
That's right, so I think that when you give the advice not to use string concatenation you should mention that the advice might not make any difference in CPython, but is still a good idea if you are concerned about portability.
$endgroup$
– Gareth Rees
Oct 20 '15 at 11:31
$begingroup$
In modern versions of CPython repeated string concatenation is usually only a little slower than join, so this is now only a worry if you want to be portable to other versions of Python like PyPy.
$endgroup$
– Gareth Rees
Oct 19 '15 at 21:09
$begingroup$
In modern versions of CPython repeated string concatenation is usually only a little slower than join, so this is now only a worry if you want to be portable to other versions of Python like PyPy.
$endgroup$
– Gareth Rees
Oct 19 '15 at 21:09
$begingroup$
@GarethRees just tested, in my Cython 3.4 joining is actually slower (by 20%) but in pypy
+=
is so slow as to be totally unusable (more than 100x the time of join and still running)$endgroup$
– Caridorc
Oct 19 '15 at 21:31
$begingroup$
@GarethRees just tested, in my Cython 3.4 joining is actually slower (by 20%) but in pypy
+=
is so slow as to be totally unusable (more than 100x the time of join and still running)$endgroup$
– Caridorc
Oct 19 '15 at 21:31
$begingroup$
That's right, so I think that when you give the advice not to use string concatenation you should mention that the advice might not make any difference in CPython, but is still a good idea if you are concerned about portability.
$endgroup$
– Gareth Rees
Oct 20 '15 at 11:31
$begingroup$
That's right, so I think that when you give the advice not to use string concatenation you should mention that the advice might not make any difference in CPython, but is still a good idea if you are concerned about portability.
$endgroup$
– Gareth Rees
Oct 20 '15 at 11:31
add a comment |
$begingroup$
Dhaval Tandale - Cognizant 3.38
New contributor
$endgroup$
add a comment |
$begingroup$
Dhaval Tandale - Cognizant 3.38
New contributor
$endgroup$
add a comment |
$begingroup$
Dhaval Tandale - Cognizant 3.38
New contributor
$endgroup$
Dhaval Tandale - Cognizant 3.38
New contributor
New contributor
answered 5 mins ago
dhavaldhaval
1
1
New contributor
New contributor
add a comment |
add a comment |
Thanks for contributing an answer to Code Review Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
Use MathJax to format equations. MathJax reference.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f108057%2fsimplified-des-encryption%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
$begingroup$
Is doing this object-oriented allowed?
$endgroup$
– Mast
Oct 19 '15 at 19:24
$begingroup$
Yes, it is allowed.
$endgroup$
– ßaron
Oct 19 '15 at 19:25
$begingroup$
What is "Simplified DES"? Is it the algorithm described here?
$endgroup$
– Gareth Rees
Oct 19 '15 at 19:25
$begingroup$
Hello @Gareth Rees, that is indeed the algorithm, i should have given the link..
$endgroup$
– ßaron
Oct 19 '15 at 19:27
1
$begingroup$
@ßaron It affects the speed here is the main reason I asked, the more recent you're using the less of a difference Caridorc's answer makes. Also to reply to people in comments make sure you @ them as people don't always got notified otherwise!
$endgroup$
– SuperBiasedMan
Oct 20 '15 at 12:47