乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      代碼被反編譯了?這兩個(gè)小技巧能幫到你

       西北望msm66g9f 2020-05-25

      后臺回復(fù)關(guān)鍵字 “黑魔法”,即可獲取明哥整理的《Python黑魔法指南


      談到 Python 的文件后綴,說眼花繚亂也不為過,來看看你遇到過哪些類型!


      .py      

      如果這個(gè)不知道,那請出門左拐,你還是充錢那個(gè)少年,沒有一絲絲改變。接著打游戲去吧…


      .pyc      

      這個(gè)后綴應(yīng)該算是除了Python 的 py 代碼外,遇到最多的一種文件類型了。

      雖然 Python 被普遍認(rèn)為是一種解釋性語言,但誰說它就不能被編譯后執(zhí)行呢?

      Python 通過 compile 生成的 pyc 文件,然后由 Python 的虛擬機(jī)執(zhí)行,相對于 py 文件來說,編譯成 pyc 本質(zhì)上和 py 沒有太大區(qū)別,只是對于這個(gè)模塊的加載速度提高了,并沒有提高代碼的執(zhí)行速度,通常情況下不用主動(dòng)去編譯 pyc 文件。

      那 pyc 文件存在的意義在哪里?

      除了略微提高的模塊加載速度外,更多的當(dāng)然是為了一定意義上的保護(hù)源碼不被泄露了。

      當(dāng)然為什么說一定意義?因?yàn)榧热挥芯幾g,就畢竟存在反編譯嘍,這個(gè)一會(huì)兒說…

      如何將 py 文件編譯成 pyc 文件呢?方法有三:

      1、使用 Python 直接編譯

      python -m sample.py

       2、py_compile

      import py_compile
      py_compile.compile('sample.py')

       3、compileall

      import compileall
      compileall.compile_file('sample.py')
      compileall.compile_dir(dirpath)

      三種方式一看便知,區(qū)別在于 compileall 可以一次遞歸編譯文件夾下所有的 py 文件


      .pyo      

      pyo 是源文件優(yōu)化編譯后的文件,pyo 文件在大小上,一般小于等于 pyc 文件。

      這個(gè)優(yōu)化沒有多大作用,只是移除了斷言。原文如下:

      When the Python interpreter is invoked with the -O flag, optimized code is generated and stored in .pyo files. The optimizer currently doesn’t help much; it only removes assert statements. When -O is used, all bytecode is optimized; .pyc files are ignored and .py files are compiled to optimized bytecode.

      使用方式:

      python -O -m py_compile sample.py

      .pyd    

      看到了前幾種,相信 d 這個(gè)字母大家猜猜就能想到,它是 Python的動(dòng)態(tài)鏈接庫;動(dòng)態(tài)鏈接庫( DLL )文件是一種可執(zhí)行文件,允許程序共享執(zhí)行特殊任務(wù)所必需的代碼和其他資源。

      你在 Python 安裝目錄的 DLL 文件夾下,就可以看到它們了。


      .pyz(w)

      從 Python 3.5 開始,定義了 .pyz 和 .pyzw 分別作為 “Python Zip 應(yīng)用” 和 “Windows 下 Python Zip 應(yīng)用” 的擴(kuò)展名。

      新增了內(nèi)置 zipapp 模塊來進(jìn)行簡單的管理,可以用 Zip 打包 Python 程序到一個(gè)可執(zhí)行 .pyz 文件。

      使用也比較簡單,但無法想 pyinstaller 等打包 exe 工具一樣脫離 Python 環(huán)境單獨(dú)運(yùn)行,而且這類文件往往拿文本編輯器就能看到它的源碼信息,總體來說還是比較雞肋。


      .exe      

      為什么會(huì)再單獨(dú)提到 exe 文件,因?yàn)?Python 有很多可以將 Python 源碼打包成 exe 的工具,從而脫離 Python 環(huán)境單獨(dú)運(yùn)行。

      python反編譯

      所謂道高一尺魔高一丈,不管是 Python、JAVA 還是 C 語言,只要有編譯,必然存在反編譯的操作。

      不管再怎么去考慮加密,勢必都有人能破解,只是成本不同而已,所以編譯只可作為一種防君子不防小人的操作。

      今天主要和大家聊聊 pyc 文件的反編譯,其中有哪些小心機(jī)的做法與陷阱。

      首先,反編譯既然是一種非正常手段,Python 自然不會(huì)原生附帶該模塊。

      我們需要先安裝依賴:

      # 安裝依賴
      pip install uncompyle6

      操作也比較簡單,命令行下輸入:

      uncompyle6 sample.pyc(pyo) > sample.py

      這就完了?說好的心機(jī)與陷阱呢?哈哈,接著看…

      使用注釋的心機(jī)

      我們來創(chuàng)建一個(gè)名為 BreezePython.py 的文件,并將下面的代碼進(jìn)行編譯和反編譯,來看看反編譯后的內(nèi)容與原始代碼有什么差異

      import platform

      def test():
          '''
          這是一個(gè)測試方法,用來驗(yàn)證反編譯
          :return: None
          '''

          # 打印系統(tǒng)詳情
          print(platform.platform())

      test()

      譯:

      python -m BreezePython.py

      反編譯:

      uncompyle6 BreezePython.cpython-37.pyc > output.py

      下來看看反編譯后的文件有什么區(qū)別吧:

      # uncompyle6 version 3.6.4
      # Python bytecode 3.7 (3394)
      # Decompiled from: Python 3.7.3 (v3.7.3:ef4ec6ed12, Mar 25 2019, 22:22:05) [MSC v.1916 64 bit (AMD64)]
      # Embedded file name: C:\Users\Administrator\Desktop\uncompile\BreezePython.py
      # Size of source mod 2**32: 453 bytes
      import platform

      def test():
          '''
          這是一個(gè)測試方法,用來驗(yàn)證反編譯
          :return: None
          '''

          print(platform.platform())


      test()
      # okay decompiling BreezePython.cpython-37.pyc

      相比于原始的代碼,有什么差別?

      沒錯(cuò),注釋…文檔注釋默認(rèn)會(huì)保留,但使用# 進(jìn)行的注釋,卻在編譯+反編譯的過程中丟失了。

      那么如果你是個(gè)心機(jī) boy,代碼注釋都用#去寫吧,即便反編譯了代碼,沒有注釋的情況下,即便我們自己也會(huì)被大段沒有注釋的代碼搞瘋掉了,哈哈。

      反編譯的陷阱

      反編譯就萬無一失么?NO…舉一個(gè)例子吧,這段代碼隨意而為,只是為了讓反編譯的時(shí)候拋出錯(cuò)誤:

      class Demo:
          def __init__(self, color):
              self.color = color

          def jduge(self):
              if not self.color:
                  return 'get None'
              if not self.color == 'red':
                  mood = 'disappointed'
                  return 'I'm %s,I like white best' % mood
              return 'get None...'


      if __name__ == '__main__':
          Main = Demo('red')
          print(Main.jduge())

      正常情況這段代碼應(yīng)該返回:get None…
      但這段代碼反編譯后成了什么樣子?

      # uncompyle6 version 3.6.4
      # Python bytecode 3.7 (3394)
      # Decompiled from: Python 3.7.3 (v3.7.3:ef4ec6ed12, Mar 25 2019, 22:22:05) [MSC v.1916 64 bit (AMD64)]
      # Embedded file name: C:\Users\Administrator\Desktop\uncompile\BreezePython.py
      # Size of source mod 2**32: 391 bytes

      class Demo:
          def __init__(self, color):
              self.color = color
          def jduge(self):
              if not self.color:
                  return 'get None'
              else:
                  mood = self.color == 'red' or 'disappointed'
                  return 'I'm %s,I like white best' % mood
              return 'get None...'

      if __name__ == '__main__':
          Main = Demo('red')
          print(Main.jduge())
      # okay decompiling __pycache__\BreezePython.cpython-37.pyc

      編譯后的代碼返回:I'm True,I like white best

      什么鬼?這編譯成什么了亂七八糟的了東西了。

      根據(jù)多年采坑經(jīng)驗(yàn),反編譯的代碼,當(dāng)遇到多個(gè)if not 的時(shí)候,最后一個(gè) if not 就會(huì)被所謂的簡要寫法而弄巧成拙,最終導(dǎo)致反編譯出錯(cuò)。

      這個(gè)是個(gè)坑,同樣你是否也可以利用它呢?

      今天的文章就到這里,希望通過這篇文章能讓你對 Python 的文件類型與編譯、反編譯操作有所了解。如果有收獲,期待你的支持與轉(zhuǎn)發(fā)。

        本站是提供個(gè)人知識管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多