2023年10月6日 星期五

用Python從FTP伺服器下載檔案

  1. FTP伺服端程式(黃底部份需要視情況變動):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
from pyftpdlib.authorizers import DummyAuthorizer
from pyftpdlib.handlers import FTPHandler
from pyftpdlib.servers import FTPServer

authorizer = DummyAuthorizer()
authorizer.add_user("demo", "1234", "C:/Users/cheng-min/AppData/Local/Programs/Python/Python311/test", perm="elradfmwMT")
authorizer.add_anonymous("C:/Users/cheng-min/AppData/Local/Programs/Python/Python311/test")

handler = FTPHandler
handler.authorizer = authorizer

server = FTPServer(("127.0.0.1", 2121), handler)
server.serve_forever()

2.FTP客戶端程式(黃底部份需要視情況變動):
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
from ftplib import FTP
import sys, getpass, os.path

host = '127.0.0.1'
port = 2121
timeout = 30
username = 'demo'
password = '1234'
remote_file = 'test6.py'
local_path = '.'  # 下載到目前的工作目錄

ftp = FTP()

try:
    ftp.connect(host, port, timeout)
    ftp.login(username, password)
    remote_file_list = ftp.nlst()  # 列出遠程目錄中的文件

    if remote_file in remote_file_list:
        local_file_path = os.path.join(local_path, remote_file)
        with open(local_file_path, 'wb') as local_file:
            ftp.retrbinary('RETR ' + remote_file, local_file.write)
        print(f'下載 {remote_file} 到 {local_file_path} 完成。')
    else:
        print(f'{remote_file} 不存在於遠程目錄 {remote_path} 中。')

except Exception as e:
    print(f'發生錯誤: {e}')

finally:
    ftp.quit()

用Python上傳檔案到FTP伺服器

 1. FTP伺服端程式(黃底部份需要視情況變動):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
from pyftpdlib.authorizers import DummyAuthorizer
from pyftpdlib.handlers import FTPHandler
from pyftpdlib.servers import FTPServer

authorizer = DummyAuthorizer()
authorizer.add_user("demo", "1234", "C:/Users/cheng-min/AppData/Local/Programs/Python/Python311/test", perm="elradfmwMT")
authorizer.add_anonymous("C:/Users/cheng-min/AppData/Local/Programs/Python/Python311/test")

handler = FTPHandler
handler.authorizer = authorizer

server = FTPServer(("127.0.0.1", 2121), handler)
server.serve_forever()

2.FTP客戶端程式(黃底部份需要視情況變動):
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
from ftplib import FTP       
import sys,getpass,os.path   
host = '127.0.0.1'       
port = 2121              
timenout = 30                
username = 'demo'           
password = '1234'          
localfile = 'test6.py'   
remotepath = 'C:/Users/cheng-min/AppData/Local/Programs/Python/Python311/test'       
f = FTP()
f.connect(host,port,timenout)  
f.login(username,password)     
#f.cwd(remotepath)             
file = open(localfile,'rb')
if os.path.isfile(localfile):
    print ('上傳 %s to %s'%(localfile, remotepath))
    f.storbinary('STOR %s' % localfile,file)  
file.close()   
f.quit() 


用Python查看FTP伺服器檔案列表實習

 1.首先要先安裝FTP伺服器套件-pyftpdlib,命令如下:

pip3 install pyftpdlib


2.設定使用者帳號和密碼,帳號設為demo,密碼是1234,命令如下:
python -m pyftpdlib --user=demo --password=1234


3.可以再開啟另一個命令提示字元,執行FTP伺服器的功能,其命令如下:
curl --user demo:1234 ftp://127.0.0.1:2121/

4.FTP用戶端的程式碼:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
import ftplib

conn = ftplib.FTP()
conn.connect('127.0.0.1', 2121)
conn.login('demo','1234')

data = []

conn.dir(data.append)

conn.quit()

for line in data:
    print ("-", line)

執行結果(以下內容會因實際而有所不同):
- drwxrwxrwx   1 owner    group           0 Nov 24  2019 .AndroidStudio3.5
- drwxrwxrwx   1 owner    group           0 Aug 26  2020 .LINE
- drwxrwxrwx   1 owner    group           0 Aug 26  2020 .QtWebEngineProcess
- drwxrwxrwx   1 owner    group           0 Feb 13  2020 .anaconda
- drwxrwxrwx   1 owner    group        4096 Nov 24  2019 .android
- -rw-rw-rw-   1 owner    group         243 Jul 11  2020 .bash_history
- drwxrwxrwx   1 owner    group           0 Oct 04 00:13 .cache
- drwxrwxrwx   1 owner    group           0 Jul 13  2020 .conda



2023年10月1日 星期日

用Python玩加密和解密

以下Python範例是參考:在Python中實現加密解密字串的多個方法

使用simplecrypt模組需要先安裝下列套件:

  1. pip3 install pycryptodome
  2. pip3 install simple-crypt --no-dependencies

範例一、使用simplecrypt模組

1
2
3
4
5
6
7
8
from simplecrypt import encrypt, decrypt
密碼 = '1234'
明文 = '虎尾鎮'
密文 = encrypt(密碼,明文)
print("密文:")
print(密文)
print("解密:")
print((decrypt(密碼,密文)).decode('utf-8'))

執行結果:
密文:
b"sc\x00\x02\xc4U\xa9.f\x82 \xafi|\xccq'\xafC\x8d\xcd\xf2\xc9\x1bY\xdaH\xdd4\xac\xa0\x90\xd8\xcd\xe32\xb0\xfe\xd2\x19\xd7a;\xc9\xa6>\x1d\xd3\xbc\x13\xcd\xe6{\xf3=\xf48\x0ef\xf4 \x8eOn\xb1Q6\xcdY\xbc\xee\xd05m\xa9\x9bt"
解密:
虎尾鎮

使用cryptocode套件,需先安裝
pip install cryptocode

範例二、使用cryptocode套件

1
2
3
4
5
6
7
8
9
import cryptocode
密碼 = 'abcd'
原文 = '虎尾鎮'
密文 = cryptocode.encrypt(原文,密碼)
明文 = cryptocode.decrypt(密文,密碼)
print("密文:")
print(密文)
print("解密:")
print(明文)

執行結果:
密文:
VwSx9yFyqo76*PQa0/eHkPBg2hNtuf39WkA==*t5NwLhneE+/dtfNvtrcBJA==*+1EJ1g9Taa84//gXLbi54A==
解密:
虎尾鎮

使用RSA方法要先安裝下列套件:
pip install rsa

範例三、使用RSA方法

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
import rsa
#產生公鑰和私鑰
公鑰,私鑰=rsa.newkeys(512)
原文 = '虎尾鎮'
print("密鑰:")
print('公鑰:', 公鑰)
print('私鑰:', 私鑰)
#加密
密文 = rsa.encrypt(原文.encode(),公鑰)
#解密  
明文 = rsa.decrypt(密文, 私鑰).decode()
print("密文:")
print(密文)
print("明文:")
print(明文)

執行結果:
密鑰:
公鑰: PublicKey(8594592785784686509010260682839316947667262798816096978717012026389533616622284117764985601422125831484792403705327792999140721708190961855402115192994553, 65537)
私鑰: PrivateKey(8594592785784686509010260682839316947667262798816096978717012026389533616622284117764985601422125831484792403705327792999140721708190961855402115192994553, 65537, 2572594514224608926976429861227381182574556270875617962852917053293307304634094336859291760891370608561922146973085512585886128568266724595957967068596561, 6804032571681137634075662172366154318044265515947545917337454507539443706876324829, 1263161617061621146332651862172501067980828672547394642120143692112631757)
密文:
b".d_@\xc3V%\t\xc2\xfb\x98'S*!\xe1\xbb\xf2\x13\x19\x87\x8ekt\xdeD6\xa5~\xdf\x9c9`\x80\x02'\xeb\x17\x8e\x03\xcf\xcaN!Z\xbe\xfd\xf5\xc1?\xd7\x88\xb3\x1c\t\xfb\x05\xce\xdf\xb3A\xfd\x95\x01"
明文:
虎尾鎮

用Python實作TCP傳送和接收程式

伺服端程式:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
import socket

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

PORT = 1060
network = '192.168.176.1'
message = '國立虎尾科技大學電機資訊學院歡迎您'

s.bind((network, PORT))
print('聆聽訊息來自 ', s.getsockname()) s.listen(5) conn, address = s.accept() print('TCP Server is connected by ' + str(address)) data = conn.recv(65535) print('TCP Server 接收訊息從 {}:\n{}'.format(address, data.decode('utf-8'))) conn.send(message.encode('utf-8')) s.close()

客戶端程式:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

PORT = 1060
network = '192.168.176.1'
message = '國立虎尾科技大學電機資訊學院有電機、光電、資訊、電子等系所'

s.connect((network, PORT))
s.send(message.encode('utf-8'))
data = s.recv(65535)
print('TCP Client 接收訊息來自{}:\n{}'.format(network, data.decode('utf-8')))

測試步驟如下:
1.先開啟IDLE程式,選擇File->New File,把伺服端程式貼上,選擇Run執行,記得存檔。
2.再開啟另一個IDLE程式,選擇File->New File,把客戶端程式貼上,選擇Run執行,記得存檔。

執行結果:
1.伺服端

2.客戶端

我們可以修訂TCP伺服端,可以持續地接受客戶端的連線以及資料。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
import socket

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

PORT = 1060
network = '192.168.1.105'
message = '國立虎尾科技大學電機資訊學院歡迎您'

s.bind((network, PORT))
print('聆聽訊息來自 ', s.getsockname())
s.listen(5)

while(1):
    conn, address = s.accept()
    print('TCP Server is connected by ' + str(address))
    data = conn.recv(65535)
    print('TCP Server 接收訊息從 {}:\n{}'.format(address, data.decode('utf-8')))
    conn.send(message.encode('utf-8'))
s.close()



用Python實作UDP傳送和接收程式

參考文章:用Python實作UDP通訊程式

客戶端程式:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)

PORT = 1060
network = '192.168.176.1'
message = '國立虎尾科技大學電機資訊學院有電機、光電、資訊、電子等系所'

s.sendto(message.encode('utf-8'), (network, PORT))
data, address = s.recvfrom(65535)
print('UDP Client 接收訊息來自 {}:\n{}'.format(address, data.decode('utf-8')))

伺服端程式:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
import socket

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)

PORT = 1060
network = '192.168.176.1'
message = '國立虎尾科技大學電機資訊學院歡迎您'

s.bind((network, PORT))
print('聆聽訊息來自 ', s.getsockname()) while True: data, address = s.recvfrom(65535) print('UDP Server 接收訊息從 {}:\n{}'.format(address, data.decode('utf-8'))) s.sendto(message.encode('utf-8'), address)

測試步驟如下:
1.先開啟IDLE程式,選擇File->New File,把伺服端程式貼上,選擇Run執行,記得存檔。
2.再開啟另一個IDLE程式,選擇File->New File,把客戶端程式貼上,選擇Run執行,記得存檔。

執行結果:
1.伺服端

2.客戶端