Count power of big numbers and then apply modulo on this numbers











up vote
-1
down vote

favorite












I have this example code in which I have very big numbers as you see. Problem is that when I use this algorithm for some small numbers, it works well, but when I use it for big numbers like in this example, this algorithm is so slow.
Can you tell me why is this algorithm so slow for that big numbers? How can I make it faster?



n = 11698030645065745910098695770921
e = 9569991810443215702618212520777
d = 7874909554574080825236064017913
m = 104228568138
m = int(m)
e = int(e)
n = int(n)
def preparation(m, n):
block_lenght= len(str(n)) - 1
m = [str(m)[i:i+block_lenght] for i in range(0, len(str(m)), block_lenght)]
return m

def encrypt(m, n, e):
m = preparation(m, n)

power = [int(i) ** e for i in m]

modulo = [i%n for i in power]

total_sum = sum(modulo)

return total_sum

m = encrypt(m, n, e)
print("m = ", m)









share|improve this question









New contributor




Brian is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.




















  • Not worth an answer yet but the pow builtins takes up to 3 arguments and actually perform what you are trying to achieve.
    – Josay
    yesterday










  • Welcome to Code Review! Please explain what you are calculating. Is this an algorithm like RSA? MathJax is available, if you need to type mathematical notation.
    – 200_success
    yesterday










  • Yes, its part of code for RSA encrypting, this "n", "m", "d" and "e" are generated from another part of code. This "m" is converted text message.
    – Brian
    yesterday






  • 1




    Welcome to Code Review! I have rolled back your last edit. Please do not update the code in your question to incorporate feedback from answers, doing so goes against the Question + Answer style of Code Review. This is not a forum where you should keep the most updated version in your question. Please see what you may and may not do after receiving answers.
    – Sᴀᴍ Onᴇᴌᴀ
    yesterday












  • Sorry for that.
    – Brian
    yesterday















up vote
-1
down vote

favorite












I have this example code in which I have very big numbers as you see. Problem is that when I use this algorithm for some small numbers, it works well, but when I use it for big numbers like in this example, this algorithm is so slow.
Can you tell me why is this algorithm so slow for that big numbers? How can I make it faster?



n = 11698030645065745910098695770921
e = 9569991810443215702618212520777
d = 7874909554574080825236064017913
m = 104228568138
m = int(m)
e = int(e)
n = int(n)
def preparation(m, n):
block_lenght= len(str(n)) - 1
m = [str(m)[i:i+block_lenght] for i in range(0, len(str(m)), block_lenght)]
return m

def encrypt(m, n, e):
m = preparation(m, n)

power = [int(i) ** e for i in m]

modulo = [i%n for i in power]

total_sum = sum(modulo)

return total_sum

m = encrypt(m, n, e)
print("m = ", m)









share|improve this question









New contributor




Brian is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.




















  • Not worth an answer yet but the pow builtins takes up to 3 arguments and actually perform what you are trying to achieve.
    – Josay
    yesterday










  • Welcome to Code Review! Please explain what you are calculating. Is this an algorithm like RSA? MathJax is available, if you need to type mathematical notation.
    – 200_success
    yesterday










  • Yes, its part of code for RSA encrypting, this "n", "m", "d" and "e" are generated from another part of code. This "m" is converted text message.
    – Brian
    yesterday






  • 1




    Welcome to Code Review! I have rolled back your last edit. Please do not update the code in your question to incorporate feedback from answers, doing so goes against the Question + Answer style of Code Review. This is not a forum where you should keep the most updated version in your question. Please see what you may and may not do after receiving answers.
    – Sᴀᴍ Onᴇᴌᴀ
    yesterday












  • Sorry for that.
    – Brian
    yesterday













up vote
-1
down vote

favorite









up vote
-1
down vote

favorite











I have this example code in which I have very big numbers as you see. Problem is that when I use this algorithm for some small numbers, it works well, but when I use it for big numbers like in this example, this algorithm is so slow.
Can you tell me why is this algorithm so slow for that big numbers? How can I make it faster?



n = 11698030645065745910098695770921
e = 9569991810443215702618212520777
d = 7874909554574080825236064017913
m = 104228568138
m = int(m)
e = int(e)
n = int(n)
def preparation(m, n):
block_lenght= len(str(n)) - 1
m = [str(m)[i:i+block_lenght] for i in range(0, len(str(m)), block_lenght)]
return m

def encrypt(m, n, e):
m = preparation(m, n)

power = [int(i) ** e for i in m]

modulo = [i%n for i in power]

total_sum = sum(modulo)

return total_sum

m = encrypt(m, n, e)
print("m = ", m)









share|improve this question









New contributor




Brian is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











I have this example code in which I have very big numbers as you see. Problem is that when I use this algorithm for some small numbers, it works well, but when I use it for big numbers like in this example, this algorithm is so slow.
Can you tell me why is this algorithm so slow for that big numbers? How can I make it faster?



n = 11698030645065745910098695770921
e = 9569991810443215702618212520777
d = 7874909554574080825236064017913
m = 104228568138
m = int(m)
e = int(e)
n = int(n)
def preparation(m, n):
block_lenght= len(str(n)) - 1
m = [str(m)[i:i+block_lenght] for i in range(0, len(str(m)), block_lenght)]
return m

def encrypt(m, n, e):
m = preparation(m, n)

power = [int(i) ** e for i in m]

modulo = [i%n for i in power]

total_sum = sum(modulo)

return total_sum

m = encrypt(m, n, e)
print("m = ", m)






performance python-3.x






share|improve this question









New contributor




Brian is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











share|improve this question









New contributor




Brian is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









share|improve this question




share|improve this question








edited yesterday









Sᴀᴍ Onᴇᴌᴀ

8,00561750




8,00561750






New contributor




Brian is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









asked yesterday









Brian

11




11




New contributor




Brian is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.





New contributor





Brian is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.






Brian is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.












  • Not worth an answer yet but the pow builtins takes up to 3 arguments and actually perform what you are trying to achieve.
    – Josay
    yesterday










  • Welcome to Code Review! Please explain what you are calculating. Is this an algorithm like RSA? MathJax is available, if you need to type mathematical notation.
    – 200_success
    yesterday










  • Yes, its part of code for RSA encrypting, this "n", "m", "d" and "e" are generated from another part of code. This "m" is converted text message.
    – Brian
    yesterday






  • 1




    Welcome to Code Review! I have rolled back your last edit. Please do not update the code in your question to incorporate feedback from answers, doing so goes against the Question + Answer style of Code Review. This is not a forum where you should keep the most updated version in your question. Please see what you may and may not do after receiving answers.
    – Sᴀᴍ Onᴇᴌᴀ
    yesterday












  • Sorry for that.
    – Brian
    yesterday


















  • Not worth an answer yet but the pow builtins takes up to 3 arguments and actually perform what you are trying to achieve.
    – Josay
    yesterday










  • Welcome to Code Review! Please explain what you are calculating. Is this an algorithm like RSA? MathJax is available, if you need to type mathematical notation.
    – 200_success
    yesterday










  • Yes, its part of code for RSA encrypting, this "n", "m", "d" and "e" are generated from another part of code. This "m" is converted text message.
    – Brian
    yesterday






  • 1




    Welcome to Code Review! I have rolled back your last edit. Please do not update the code in your question to incorporate feedback from answers, doing so goes against the Question + Answer style of Code Review. This is not a forum where you should keep the most updated version in your question. Please see what you may and may not do after receiving answers.
    – Sᴀᴍ Onᴇᴌᴀ
    yesterday












  • Sorry for that.
    – Brian
    yesterday
















Not worth an answer yet but the pow builtins takes up to 3 arguments and actually perform what you are trying to achieve.
– Josay
yesterday




Not worth an answer yet but the pow builtins takes up to 3 arguments and actually perform what you are trying to achieve.
– Josay
yesterday












Welcome to Code Review! Please explain what you are calculating. Is this an algorithm like RSA? MathJax is available, if you need to type mathematical notation.
– 200_success
yesterday




Welcome to Code Review! Please explain what you are calculating. Is this an algorithm like RSA? MathJax is available, if you need to type mathematical notation.
– 200_success
yesterday












Yes, its part of code for RSA encrypting, this "n", "m", "d" and "e" are generated from another part of code. This "m" is converted text message.
– Brian
yesterday




Yes, its part of code for RSA encrypting, this "n", "m", "d" and "e" are generated from another part of code. This "m" is converted text message.
– Brian
yesterday




1




1




Welcome to Code Review! I have rolled back your last edit. Please do not update the code in your question to incorporate feedback from answers, doing so goes against the Question + Answer style of Code Review. This is not a forum where you should keep the most updated version in your question. Please see what you may and may not do after receiving answers.
– Sᴀᴍ Onᴇᴌᴀ
yesterday






Welcome to Code Review! I have rolled back your last edit. Please do not update the code in your question to incorporate feedback from answers, doing so goes against the Question + Answer style of Code Review. This is not a forum where you should keep the most updated version in your question. Please see what you may and may not do after receiving answers.
– Sᴀᴍ Onᴇᴌᴀ
yesterday














Sorry for that.
– Brian
yesterday




Sorry for that.
– Brian
yesterday










2 Answers
2






active

oldest

votes

















up vote
1
down vote













Your spelling of length is unconventional, and will cause errors.



Calculating the full result will generate a large number, slowing computation. It's better to reduce the partial results as you compute the power, and keep the partial result mod n - you'll probably want to use binary exponentiation instead of the ** operator so that you can apply the modulus to the intermediate results.



I don't see what m = int(m) and similar lines are intended to achieve - probably worth a comment there.



How is the final (partial) block handled? That seems to be missing altogether.






share|improve this answer




























    up vote
    1
    down vote













    Avoid the amount of duplicated/useless operations



    The function int is called on integers which is useless.



    The str function is called many times on the same inputs which can be avoided with temporary variables.



    You iterate (indirectly) 3 times over the result of preparation2, this could be done with a single operation.



    At this stage, you can write something like:



    def preparation2(m, n):
    n_str = str(n)
    m_str = str(m)
    block_len = len(n_str) - 1
    return [m_str[i:i+block_len] for i in range(0, len(m_str), block_len)]

    def encrypt2(m, n, e):
    return sum((int(i)**e) % n for i in preparation2(m, n))


    Builtin



    The pow builtins takes up to 3 arguments and actually perform what you are trying to achieve in a much more efficient way.



    def encrypt2(m, n, e):
    return sum(pow(int(i), e, n) for i in preparation2(m, n))


    Final code and benchmark



    I wrote the following code to test the original code and the improved code and ensuring that the behavior is not broken on inputs of increasing sizes:



    def preparation(m, n):
    block_lenght= len(str(n)) - 1
    m = [str(m)[i:i+block_lenght] for i in range(0, len(str(m)), block_lenght)]
    return m

    def encrypt(m, n, e):
    m = preparation(m, n)

    power = [int(i) ** e for i in m]

    modulo = [i%n for i in power]

    total_sum = sum(modulo)

    return total_sum


    def preparation2(m, n):
    n_str = str(n)
    m_str = str(m)
    block_len = len(n_str) - 1
    return [m_str[i:i+block_len] for i in range(0, len(m_str), block_len)]

    def encrypt2(m, n, e):
    return sum(pow(int(i), e, n) for i in preparation2(m, n))


    import time

    TEST_CASES = [
    (116, 956, 787, 10),
    (1169, 9569, 7874, 10),
    (116980, 956999, 787490, 104),
    (1169803, 956999, 787490, 104),
    (11698030, 9569991, 7874909, 1042),
    (11698030645, 95699918104, 787490955457, 10422),
    (116980306450657459, 956999181044321570, 787490955457408082, 104228568),
    (11698030645065745910098695770921, 9569991810443215702618212520777, 7874909554574080825236064017913, 104228568138),
    ]
    SEP = " "
    print("Comparison", SEP, "Original solution", SEP, "Improved solution")
    for (n, e, d, m) in TEST_CASES:
    start = time.perf_counter()
    out = encrypt(m, n, e)
    time_sol1 = time.perf_counter() - start

    start = time.perf_counter()
    out2 = encrypt2(m, n, e)
    time_sol2 = time.perf_counter() - start
    if out != out2:
    print("Different outputs", SEP, out, SEP, out2)
    break
    else:
    print("Times", SEP, time_sol1, SEP, time_sol2)


    And the results:



    Comparison        Original solution        Improved solution
    Times 4.408881068229675e-05 2.5639310479164124e-05
    Times 0.00031274929642677307 1.0897871106863022e-05
    Times 0.587213734164834 2.9506627470254898e-05
    Times 0.5985749792307615 2.992432564496994e-05
    Times 62.84936385508627 3.45488078892231e-05


    Then it becomes too slow to have results....






    share|improve this answer























    • So I modified my code as you adviced me, but its still slow
      – Brian
      yesterday










    • @Brian Oh, I am surprised... Did you notice that the functions names are not exactly the one from your code ?
      – Josay
      yesterday










    • Yes, in a minute I modify my question to current form
      – Brian
      yesterday










    • Any other advices? My current code you can see in modified top question.
      – Brian
      yesterday










    • @Brian I've updated my answer to add more details
      – Josay
      21 hours ago











    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',
    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
    });


    }
    });






    Brian is a new contributor. Be nice, and check out our Code of Conduct.










    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f209012%2fcount-power-of-big-numbers-and-then-apply-modulo-on-this-numbers%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    1
    down vote













    Your spelling of length is unconventional, and will cause errors.



    Calculating the full result will generate a large number, slowing computation. It's better to reduce the partial results as you compute the power, and keep the partial result mod n - you'll probably want to use binary exponentiation instead of the ** operator so that you can apply the modulus to the intermediate results.



    I don't see what m = int(m) and similar lines are intended to achieve - probably worth a comment there.



    How is the final (partial) block handled? That seems to be missing altogether.






    share|improve this answer

























      up vote
      1
      down vote













      Your spelling of length is unconventional, and will cause errors.



      Calculating the full result will generate a large number, slowing computation. It's better to reduce the partial results as you compute the power, and keep the partial result mod n - you'll probably want to use binary exponentiation instead of the ** operator so that you can apply the modulus to the intermediate results.



      I don't see what m = int(m) and similar lines are intended to achieve - probably worth a comment there.



      How is the final (partial) block handled? That seems to be missing altogether.






      share|improve this answer























        up vote
        1
        down vote










        up vote
        1
        down vote









        Your spelling of length is unconventional, and will cause errors.



        Calculating the full result will generate a large number, slowing computation. It's better to reduce the partial results as you compute the power, and keep the partial result mod n - you'll probably want to use binary exponentiation instead of the ** operator so that you can apply the modulus to the intermediate results.



        I don't see what m = int(m) and similar lines are intended to achieve - probably worth a comment there.



        How is the final (partial) block handled? That seems to be missing altogether.






        share|improve this answer












        Your spelling of length is unconventional, and will cause errors.



        Calculating the full result will generate a large number, slowing computation. It's better to reduce the partial results as you compute the power, and keep the partial result mod n - you'll probably want to use binary exponentiation instead of the ** operator so that you can apply the modulus to the intermediate results.



        I don't see what m = int(m) and similar lines are intended to achieve - probably worth a comment there.



        How is the final (partial) block handled? That seems to be missing altogether.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered yesterday









        Toby Speight

        23.1k538110




        23.1k538110
























            up vote
            1
            down vote













            Avoid the amount of duplicated/useless operations



            The function int is called on integers which is useless.



            The str function is called many times on the same inputs which can be avoided with temporary variables.



            You iterate (indirectly) 3 times over the result of preparation2, this could be done with a single operation.



            At this stage, you can write something like:



            def preparation2(m, n):
            n_str = str(n)
            m_str = str(m)
            block_len = len(n_str) - 1
            return [m_str[i:i+block_len] for i in range(0, len(m_str), block_len)]

            def encrypt2(m, n, e):
            return sum((int(i)**e) % n for i in preparation2(m, n))


            Builtin



            The pow builtins takes up to 3 arguments and actually perform what you are trying to achieve in a much more efficient way.



            def encrypt2(m, n, e):
            return sum(pow(int(i), e, n) for i in preparation2(m, n))


            Final code and benchmark



            I wrote the following code to test the original code and the improved code and ensuring that the behavior is not broken on inputs of increasing sizes:



            def preparation(m, n):
            block_lenght= len(str(n)) - 1
            m = [str(m)[i:i+block_lenght] for i in range(0, len(str(m)), block_lenght)]
            return m

            def encrypt(m, n, e):
            m = preparation(m, n)

            power = [int(i) ** e for i in m]

            modulo = [i%n for i in power]

            total_sum = sum(modulo)

            return total_sum


            def preparation2(m, n):
            n_str = str(n)
            m_str = str(m)
            block_len = len(n_str) - 1
            return [m_str[i:i+block_len] for i in range(0, len(m_str), block_len)]

            def encrypt2(m, n, e):
            return sum(pow(int(i), e, n) for i in preparation2(m, n))


            import time

            TEST_CASES = [
            (116, 956, 787, 10),
            (1169, 9569, 7874, 10),
            (116980, 956999, 787490, 104),
            (1169803, 956999, 787490, 104),
            (11698030, 9569991, 7874909, 1042),
            (11698030645, 95699918104, 787490955457, 10422),
            (116980306450657459, 956999181044321570, 787490955457408082, 104228568),
            (11698030645065745910098695770921, 9569991810443215702618212520777, 7874909554574080825236064017913, 104228568138),
            ]
            SEP = " "
            print("Comparison", SEP, "Original solution", SEP, "Improved solution")
            for (n, e, d, m) in TEST_CASES:
            start = time.perf_counter()
            out = encrypt(m, n, e)
            time_sol1 = time.perf_counter() - start

            start = time.perf_counter()
            out2 = encrypt2(m, n, e)
            time_sol2 = time.perf_counter() - start
            if out != out2:
            print("Different outputs", SEP, out, SEP, out2)
            break
            else:
            print("Times", SEP, time_sol1, SEP, time_sol2)


            And the results:



            Comparison        Original solution        Improved solution
            Times 4.408881068229675e-05 2.5639310479164124e-05
            Times 0.00031274929642677307 1.0897871106863022e-05
            Times 0.587213734164834 2.9506627470254898e-05
            Times 0.5985749792307615 2.992432564496994e-05
            Times 62.84936385508627 3.45488078892231e-05


            Then it becomes too slow to have results....






            share|improve this answer























            • So I modified my code as you adviced me, but its still slow
              – Brian
              yesterday










            • @Brian Oh, I am surprised... Did you notice that the functions names are not exactly the one from your code ?
              – Josay
              yesterday










            • Yes, in a minute I modify my question to current form
              – Brian
              yesterday










            • Any other advices? My current code you can see in modified top question.
              – Brian
              yesterday










            • @Brian I've updated my answer to add more details
              – Josay
              21 hours ago















            up vote
            1
            down vote













            Avoid the amount of duplicated/useless operations



            The function int is called on integers which is useless.



            The str function is called many times on the same inputs which can be avoided with temporary variables.



            You iterate (indirectly) 3 times over the result of preparation2, this could be done with a single operation.



            At this stage, you can write something like:



            def preparation2(m, n):
            n_str = str(n)
            m_str = str(m)
            block_len = len(n_str) - 1
            return [m_str[i:i+block_len] for i in range(0, len(m_str), block_len)]

            def encrypt2(m, n, e):
            return sum((int(i)**e) % n for i in preparation2(m, n))


            Builtin



            The pow builtins takes up to 3 arguments and actually perform what you are trying to achieve in a much more efficient way.



            def encrypt2(m, n, e):
            return sum(pow(int(i), e, n) for i in preparation2(m, n))


            Final code and benchmark



            I wrote the following code to test the original code and the improved code and ensuring that the behavior is not broken on inputs of increasing sizes:



            def preparation(m, n):
            block_lenght= len(str(n)) - 1
            m = [str(m)[i:i+block_lenght] for i in range(0, len(str(m)), block_lenght)]
            return m

            def encrypt(m, n, e):
            m = preparation(m, n)

            power = [int(i) ** e for i in m]

            modulo = [i%n for i in power]

            total_sum = sum(modulo)

            return total_sum


            def preparation2(m, n):
            n_str = str(n)
            m_str = str(m)
            block_len = len(n_str) - 1
            return [m_str[i:i+block_len] for i in range(0, len(m_str), block_len)]

            def encrypt2(m, n, e):
            return sum(pow(int(i), e, n) for i in preparation2(m, n))


            import time

            TEST_CASES = [
            (116, 956, 787, 10),
            (1169, 9569, 7874, 10),
            (116980, 956999, 787490, 104),
            (1169803, 956999, 787490, 104),
            (11698030, 9569991, 7874909, 1042),
            (11698030645, 95699918104, 787490955457, 10422),
            (116980306450657459, 956999181044321570, 787490955457408082, 104228568),
            (11698030645065745910098695770921, 9569991810443215702618212520777, 7874909554574080825236064017913, 104228568138),
            ]
            SEP = " "
            print("Comparison", SEP, "Original solution", SEP, "Improved solution")
            for (n, e, d, m) in TEST_CASES:
            start = time.perf_counter()
            out = encrypt(m, n, e)
            time_sol1 = time.perf_counter() - start

            start = time.perf_counter()
            out2 = encrypt2(m, n, e)
            time_sol2 = time.perf_counter() - start
            if out != out2:
            print("Different outputs", SEP, out, SEP, out2)
            break
            else:
            print("Times", SEP, time_sol1, SEP, time_sol2)


            And the results:



            Comparison        Original solution        Improved solution
            Times 4.408881068229675e-05 2.5639310479164124e-05
            Times 0.00031274929642677307 1.0897871106863022e-05
            Times 0.587213734164834 2.9506627470254898e-05
            Times 0.5985749792307615 2.992432564496994e-05
            Times 62.84936385508627 3.45488078892231e-05


            Then it becomes too slow to have results....






            share|improve this answer























            • So I modified my code as you adviced me, but its still slow
              – Brian
              yesterday










            • @Brian Oh, I am surprised... Did you notice that the functions names are not exactly the one from your code ?
              – Josay
              yesterday










            • Yes, in a minute I modify my question to current form
              – Brian
              yesterday










            • Any other advices? My current code you can see in modified top question.
              – Brian
              yesterday










            • @Brian I've updated my answer to add more details
              – Josay
              21 hours ago













            up vote
            1
            down vote










            up vote
            1
            down vote









            Avoid the amount of duplicated/useless operations



            The function int is called on integers which is useless.



            The str function is called many times on the same inputs which can be avoided with temporary variables.



            You iterate (indirectly) 3 times over the result of preparation2, this could be done with a single operation.



            At this stage, you can write something like:



            def preparation2(m, n):
            n_str = str(n)
            m_str = str(m)
            block_len = len(n_str) - 1
            return [m_str[i:i+block_len] for i in range(0, len(m_str), block_len)]

            def encrypt2(m, n, e):
            return sum((int(i)**e) % n for i in preparation2(m, n))


            Builtin



            The pow builtins takes up to 3 arguments and actually perform what you are trying to achieve in a much more efficient way.



            def encrypt2(m, n, e):
            return sum(pow(int(i), e, n) for i in preparation2(m, n))


            Final code and benchmark



            I wrote the following code to test the original code and the improved code and ensuring that the behavior is not broken on inputs of increasing sizes:



            def preparation(m, n):
            block_lenght= len(str(n)) - 1
            m = [str(m)[i:i+block_lenght] for i in range(0, len(str(m)), block_lenght)]
            return m

            def encrypt(m, n, e):
            m = preparation(m, n)

            power = [int(i) ** e for i in m]

            modulo = [i%n for i in power]

            total_sum = sum(modulo)

            return total_sum


            def preparation2(m, n):
            n_str = str(n)
            m_str = str(m)
            block_len = len(n_str) - 1
            return [m_str[i:i+block_len] for i in range(0, len(m_str), block_len)]

            def encrypt2(m, n, e):
            return sum(pow(int(i), e, n) for i in preparation2(m, n))


            import time

            TEST_CASES = [
            (116, 956, 787, 10),
            (1169, 9569, 7874, 10),
            (116980, 956999, 787490, 104),
            (1169803, 956999, 787490, 104),
            (11698030, 9569991, 7874909, 1042),
            (11698030645, 95699918104, 787490955457, 10422),
            (116980306450657459, 956999181044321570, 787490955457408082, 104228568),
            (11698030645065745910098695770921, 9569991810443215702618212520777, 7874909554574080825236064017913, 104228568138),
            ]
            SEP = " "
            print("Comparison", SEP, "Original solution", SEP, "Improved solution")
            for (n, e, d, m) in TEST_CASES:
            start = time.perf_counter()
            out = encrypt(m, n, e)
            time_sol1 = time.perf_counter() - start

            start = time.perf_counter()
            out2 = encrypt2(m, n, e)
            time_sol2 = time.perf_counter() - start
            if out != out2:
            print("Different outputs", SEP, out, SEP, out2)
            break
            else:
            print("Times", SEP, time_sol1, SEP, time_sol2)


            And the results:



            Comparison        Original solution        Improved solution
            Times 4.408881068229675e-05 2.5639310479164124e-05
            Times 0.00031274929642677307 1.0897871106863022e-05
            Times 0.587213734164834 2.9506627470254898e-05
            Times 0.5985749792307615 2.992432564496994e-05
            Times 62.84936385508627 3.45488078892231e-05


            Then it becomes too slow to have results....






            share|improve this answer














            Avoid the amount of duplicated/useless operations



            The function int is called on integers which is useless.



            The str function is called many times on the same inputs which can be avoided with temporary variables.



            You iterate (indirectly) 3 times over the result of preparation2, this could be done with a single operation.



            At this stage, you can write something like:



            def preparation2(m, n):
            n_str = str(n)
            m_str = str(m)
            block_len = len(n_str) - 1
            return [m_str[i:i+block_len] for i in range(0, len(m_str), block_len)]

            def encrypt2(m, n, e):
            return sum((int(i)**e) % n for i in preparation2(m, n))


            Builtin



            The pow builtins takes up to 3 arguments and actually perform what you are trying to achieve in a much more efficient way.



            def encrypt2(m, n, e):
            return sum(pow(int(i), e, n) for i in preparation2(m, n))


            Final code and benchmark



            I wrote the following code to test the original code and the improved code and ensuring that the behavior is not broken on inputs of increasing sizes:



            def preparation(m, n):
            block_lenght= len(str(n)) - 1
            m = [str(m)[i:i+block_lenght] for i in range(0, len(str(m)), block_lenght)]
            return m

            def encrypt(m, n, e):
            m = preparation(m, n)

            power = [int(i) ** e for i in m]

            modulo = [i%n for i in power]

            total_sum = sum(modulo)

            return total_sum


            def preparation2(m, n):
            n_str = str(n)
            m_str = str(m)
            block_len = len(n_str) - 1
            return [m_str[i:i+block_len] for i in range(0, len(m_str), block_len)]

            def encrypt2(m, n, e):
            return sum(pow(int(i), e, n) for i in preparation2(m, n))


            import time

            TEST_CASES = [
            (116, 956, 787, 10),
            (1169, 9569, 7874, 10),
            (116980, 956999, 787490, 104),
            (1169803, 956999, 787490, 104),
            (11698030, 9569991, 7874909, 1042),
            (11698030645, 95699918104, 787490955457, 10422),
            (116980306450657459, 956999181044321570, 787490955457408082, 104228568),
            (11698030645065745910098695770921, 9569991810443215702618212520777, 7874909554574080825236064017913, 104228568138),
            ]
            SEP = " "
            print("Comparison", SEP, "Original solution", SEP, "Improved solution")
            for (n, e, d, m) in TEST_CASES:
            start = time.perf_counter()
            out = encrypt(m, n, e)
            time_sol1 = time.perf_counter() - start

            start = time.perf_counter()
            out2 = encrypt2(m, n, e)
            time_sol2 = time.perf_counter() - start
            if out != out2:
            print("Different outputs", SEP, out, SEP, out2)
            break
            else:
            print("Times", SEP, time_sol1, SEP, time_sol2)


            And the results:



            Comparison        Original solution        Improved solution
            Times 4.408881068229675e-05 2.5639310479164124e-05
            Times 0.00031274929642677307 1.0897871106863022e-05
            Times 0.587213734164834 2.9506627470254898e-05
            Times 0.5985749792307615 2.992432564496994e-05
            Times 62.84936385508627 3.45488078892231e-05


            Then it becomes too slow to have results....







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited 21 hours ago

























            answered yesterday









            Josay

            24.6k13783




            24.6k13783












            • So I modified my code as you adviced me, but its still slow
              – Brian
              yesterday










            • @Brian Oh, I am surprised... Did you notice that the functions names are not exactly the one from your code ?
              – Josay
              yesterday










            • Yes, in a minute I modify my question to current form
              – Brian
              yesterday










            • Any other advices? My current code you can see in modified top question.
              – Brian
              yesterday










            • @Brian I've updated my answer to add more details
              – Josay
              21 hours ago


















            • So I modified my code as you adviced me, but its still slow
              – Brian
              yesterday










            • @Brian Oh, I am surprised... Did you notice that the functions names are not exactly the one from your code ?
              – Josay
              yesterday










            • Yes, in a minute I modify my question to current form
              – Brian
              yesterday










            • Any other advices? My current code you can see in modified top question.
              – Brian
              yesterday










            • @Brian I've updated my answer to add more details
              – Josay
              21 hours ago
















            So I modified my code as you adviced me, but its still slow
            – Brian
            yesterday




            So I modified my code as you adviced me, but its still slow
            – Brian
            yesterday












            @Brian Oh, I am surprised... Did you notice that the functions names are not exactly the one from your code ?
            – Josay
            yesterday




            @Brian Oh, I am surprised... Did you notice that the functions names are not exactly the one from your code ?
            – Josay
            yesterday












            Yes, in a minute I modify my question to current form
            – Brian
            yesterday




            Yes, in a minute I modify my question to current form
            – Brian
            yesterday












            Any other advices? My current code you can see in modified top question.
            – Brian
            yesterday




            Any other advices? My current code you can see in modified top question.
            – Brian
            yesterday












            @Brian I've updated my answer to add more details
            – Josay
            21 hours ago




            @Brian I've updated my answer to add more details
            – Josay
            21 hours ago










            Brian is a new contributor. Be nice, and check out our Code of Conduct.










            draft saved

            draft discarded


















            Brian is a new contributor. Be nice, and check out our Code of Conduct.













            Brian is a new contributor. Be nice, and check out our Code of Conduct.












            Brian is a new contributor. Be nice, and check out our Code of Conduct.
















            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.





            Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


            Please pay close attention to the following guidance:


            • 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.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f209012%2fcount-power-of-big-numbers-and-then-apply-modulo-on-this-numbers%23new-answer', 'question_page');
            }
            );

            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







            Popular posts from this blog

            Morgemoulin

            Scott Moir

            Souastre