Những bài tập đơn giản về xử lý chuỗi trong VBA (1 người xem)

Liên hệ QC

Người dùng đang xem chủ đề này

ChanhTQ@

0901452không62
Tham gia
5/9/08
Bài viết
4,254
Được thích
4,861
BÀI TẬP 1:

Tôi có 1 mệnh đề : "TRI THUC LA SUC MANH"

Xin nhờ các bạn mã hóa mệnh đề này để tôi gởi cho CIA với chìa khóa mã như sau:

Kí tự|Thay bằng
F|A
G|B
H|C
..|..
Z|U
A|V
B|W
C|X
D|Y
E|Z

Đáp án: ". . . . HVIC"
 
BÀI TẬP 1:

Tôi có 1 mệnh đề : "TRI THUC LA SUC MANH"

Xin nhờ các bạn mã hóa mệnh đề này để tôi gởi cho CIA với chìa khóa mã như sau:

Kí tự|Thay bằng
F|A
G|B
H|C
..|..
Z|U
A|V
B|W
C|X
D|Y
E|Z

Đáp án: ". . . . HVIC"

Tranh thủ đang học, đang vọc VBA

OMD OCPX GV NPX HVIC

Mã:
Function Encrypt(ByVal text As String) As String
Dim tmp As String, k As Long, code As Byte
    text = UCase(text)
    For k = 1 To Len(text)
        code = Asc(Mid(text, k, 1))
        If code > 64 And code < 70 Then
            code = code + 21
        ElseIf code > 69 And code < 91 Then
            code = code - 5
        End If
        tmp = tmp & Chr(code)
    Next
    Encrypt = tmp
End Function
 
Upvote 0
Anh chàng Chuot0106 này thiệt tình!

BÀI 2:

Các bạn hãy viết 1 hàm có thể dịch đoạn văn bản nào đó theo cả chiều thuận & chiều ngược lại

Hàm có cú fáp = MaHoa5(Txt As String, Optional Thuan As Boolean = True)

Ví dụ:= MaHoa5("TRI THUC LA SUC MANH") => "OMD OCPX GV NPX HVIC"

&=MaHoa5( "OMD OCPX GV NPX HVIC", FALSE)= "TRI THUC LA SUC MANH"


 
Lần chỉnh sửa cuối:
Upvote 0
BÀI 2:

Các bạn hãy viết 1 hàm có thể dịch đoạn văn bản nào đó theo cả chiều thuận & chiều ngược lại

Hàm có cú fáp = MaHoa5(Txt As String, Optional Thuan As Boolean = True)

Ví dụ:= MaHoa5("TRI THUC LA SUC MANH") => "OMD OCPX GV NPX HVIC"

&=MaHoa5( "OMD OCPX GV NPX HVIC", FALSE)= "TRI THUC LA SUC MANH"



Mã:
Function Encrypt(ByVal text As String, ByVal enc As Boolean) As String
'    enc = True --> Ma hoa, = FALSE --> Giai ma
Dim tmp As String, k As Long, code As Byte
    text = UCase(text)
    For k = 1 To Len(text)
        code = Asc(Mid(text, k, 1))
        If code > 64 And code < 91 Then
            If enc Then
                code = code + 21
            Else
                code = code - 21
            End If
            If code > 90 Then
                code = code - 26
            ElseIf code < 65 Then
                code = code + 26
            End If
        End If
        tmp = tmp & Chr(code)
    Next
    Encrypt = tmp
End Function
 
Upvote 0
Làm cho việc đoạn mã khó giải hơn, bằng cách

BÀI 3

Ta cũng dùng 26 chữ cái tiếng Anh làm mã thay thế; Nhưng các khoảng trống giữa các từ (tiếng Việt) được thay bằng các từ "F", "J", "W" hay "Z"


Lúc đó mệnh đề ở bài 1 sẽ có đáp án là "OMDAOCPXAGVANPXAHVIC"

(Mình tạm gán tên khóa mật mã này là "504")
 
Upvote 0
Chuyển mã chuỗi theo độ lệch.
Theo đề bài, để chuyển F ra A thì độ lệch là -5
Nếu muốn giải mã thì đổi dấu độ lẹch

Mã:
' gài mã chuỗi ký tự theo luật độ lệch bảng ký tự A-Z
Function MaKyTu(ByVal s As String, ByVal doLech As Integer) As String
Const MAUTU = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
Dim bm As String, i As Integer, c As String
' lập bảng tra
If doLech < 0 Then
bm = Space(Asc("A") - 1) & Right(MAUTU, -doLech) & MAUTU
Else
bm = Space(Asc("A") - 1 - doLech) & MAUTU & Left(MAUTU, doLech)
End If
' dùng bảng tra để chuyển mã
For i = 1 To Len(s)
c = Mid(s, i, 1)
If c >= "A" And c <= "Z" Then Mid(s, i, 1) = Mid(bm, Asc(c))
Next i
MaKyTu = s
End Function

MaKyTu("TRI THUC LA SUC MANH", -5) = "OMD OCPX GV NPX HVIC"
MaKyTu("OMD OCPX GV NPX HVIC", 5) = "TRI THUC LA SUC MANH"
MaKyTu(MaKyTu("TRI THUC LA SUC MANH", -5), 5) = "TRI THUC LA SUC MANH"
 
Upvote 0
Trước khi đề ra các bài tập tiếp theo, mình xin đề cập đến hình vuông Vigenère

Cách viết mã hóa theo ba bài tập bên trên là cách viết đã có hàng ngàn năm trước thế kỷ 16;
Tuy nhiên mã khóa như vậy đến lúc bấy giờ đã vô củng đơn giản & rất dễ bị bẽ khóa!

Vào khoảng năm 1460, Alberti đề xuất sử dụng 2 bảng mã chữ cái (hoặc nhiều hơn), được dùng luân fiên nhau trong quá trình mã hóa.

Ví dụ bảng chữ cái thường:
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

Bảng chữ cái mật mã có khóa là GO sẽ như sau:
G O P Q R S T U V W X Y Z A B C D E F H I J K L M N

& bảng chữ cái có mật mã có khóa là TO sẽ như sau:
TO P Q R S U V W X Y Z A B C D E F G H I J K L M N

Như vậy để mã hóa cụm từ "GIAI FAP EXCEL" ta sẽ có cụm từ:
"TWGW STC .. . "

Đây sẽ là dạng bài tập sắp tới của chúng ta

Chúc vui vẻ!
 
Upvote 0
Bài tập chuyển tiếp


BÀI TẬP 4

Trước khi đi vào mã hóa & giải mã dạng bài tập ứng dụng hình vuông Vigenère fức tập nêu trên, xin các bạn thử sức với bài tập sau đây

Ta có bảng chữ cái tiếng Việt như sau

A B C D E G H I K L M N O P Q S T U V X Y

Và dẫy đễ mã hóa có tên là HOASUNG như dưới đây:

H O A S U N G I K L M P Q T V X Y A B C D E

Các bạn hãy mã hóa cụm từ "TRI THUC LA SUC MANH" giúp nha.
 
Upvote 0
BÀI 3

Ta cũng dùng 26 chữ cái tiếng Anh làm mã thay thế; Nhưng các khoảng trống giữa các từ (tiếng Việt) được thay bằng các từ "F", "J", "W" hay "Z"


Lúc đó mệnh đề ở bài 1 sẽ có đáp án là "OMDAOCPXAGVANPXAHVIC"

(Mình tạm gán tên khóa mật mã này là "504")

Tôi không hiểu chỗ đỏ đỏ. Vì theo đáp án thì bạn luôn thay dấu cách bằng F chứ có thay bằng J, W hay Z đâu nhỉ.
Hay là mọi dấu cách đều thay bằng một ký tự duy nhất chọn sẵn là F, hoặc J, hoặc W hoặc Z?
-------------
Bảng tra theo thứ tự A-Y dễ bẻ khóa hơn là bảng tra không theo thứ tự. Ta cũng có thể có bảng tra chứa những ký tự ngoài tập A-Y, vd. ":", ",", ".", 0-9 v...v xáo trộn không theo thứ tự.
Ta có thể dùng bảng tra mặc định hoặc dùng 1 bảng tra một thời gian rồi chuyển sang bảng tra khác đề phòng KGB (là thằng bạn) đã bẻ được khóa.
Tôi làm cho trường hợp hơi khác. Bảng tra có thể tùy ý và không theo thứ tự nhưng không chứa F, J, W và Z. Những ký tự này dùng để thay vào những chỗ có dấu cách theo chu kỳ F, J, W và Z. Tức vd. dấu cách thứ 2 và thứ 6 được thay bằng J.

Mã:
Function Encrypt(ByVal text As String, ByVal offset As Long, Optional ByVal bangtra As String = "") As String
'    neu Ma voi offset = a thi Giai Ma voi offset = -a
'    bangtra khong duoc co cac ky tu F, J, W, Z la cac ky tu dung thay cho dau cach - SPACE
'    cac dau cach trong text theo chu ky F, J, W, Z
Const spaces = "FJWZ"
Const default = "ABCDEGHIKLMNOPQRSTUVXY"
Dim tmp As String, k As Long, code As Byte, dic As Object, c As String, pos As Long, c1 As String
    text = UCase(text)
    If bangtra = "" Then bangtra = default
    Set dic = CreateObject("Scripting.Dictionary")
'    cho cac cap ky tu (ky_tu, ky_tu_thay_the) vao tu dien
    For k = 1 To Len(bangtra)
        c = Mid(bangtra, k, 1)
        If Not dic.exists(c) Then dic.Add c, Mid(bangtra, ((k - 1 + offset + Len(bangtra)) Mod Len(bangtra)) + 1, 1)
    Next
'    chuyen tung ky tu thanh ky tu thay the
    For k = 1 To Len(text)
'        doc ky tu
        c = Mid(text, k, 1)
'        neu la dau cach thi thay bang F, J, W hoac Z
        If Asc(c) = 32 Then
            c = Mid(spaces, (pos Mod 4) + 1, 1)
            pos = pos + 1
'        neu la ky tu thay the cho dau cach thi chuyen thanh dau cach
        ElseIf InStr(1, spaces, c) > 0 Then
            c = Chr(32)
'        neu la ky tu trong bangtra thi chuyen thanh ky tu thay the. Neu khong thi de nguyen
        ElseIf dic.exists(c) Then
            c = dic.Item(c)
        End If
        tmp = tmp & c
    Next
    Encrypt = tmp
End Function

Sub test()
Dim s As String
    s = Encrypt("TRI THUC LA SUC MANH?", -5)
    Debug.Print s
    s = Encrypt(s, 5)
    Debug.Print s
    Debug.Print "--------------"
    s = Encrypt("TRI THUC LA SUC MANH", -5, "ADBCEGHIKLONMPQRUTSXYV")
    Debug.Print s
    s = Encrypt(s, 5, "ADBCEGHIKLONMPQRUTSXYV")
    Debug.Print s
    Debug.Print "--------------"
    s = Encrypt("TOI THICH CO BE HANG XOM!", 7)
    Debug.Print s
    s = Encrypt(s, -7)
    Debug.Print s
End Sub

Kết quả:

OMCFOBPVJETWNPVZGTHB?
TRI THUC LA SUC MANH?
--------------
MOBFMDNYJETWPNYZITHD
TRI THUC LA SUC MANH
--------------
CVQFCPQLPJLVWKNZPIUOFGVT!
TOI THICH CO BE HANG XOM!
 
Upvote 0
[thongbao]
(1) Tôi không hiểu chỗ đỏ đỏ. Vì theo đáp án thì bạn luôn thay dấu cách bằng F chứ có thay bằng J, W hay Z đâu nhỉ.
Hay là mọi dấu cách đều thay bằng một ký tự duy nhất chọn sẵn là F, hoặc J, hoặc W hoặc Z?
-------------
(2) Bảng tra theo thứ tự A-Y dễ bẻ khóa hơn là bảng tra không theo thứ tự. Ta cũng có thể có bảng tra chứa những ký tự ngoài tập A-Y, vd. ":", ",", ".", 0-9 v...v xáo trộn không theo thứ tự.
[/thongbao]

(1) Đúng là bạn đã fát hiện ra vấn đề còn thiếu sót trong đáp án; Bạn quá hay luôn!

(2) Mục tiêu của người mã hóa là:

Người cần đọc rất thuận tiện khi đọc đoạn mã hóa
Người không fép đọc sẽ khó đủ thời gian để hóa giải đoạn mã đó;

Vì vậy mà người ta mới nói đến khóa mật mã;

Ví dụ khóa là D O N G T H A P M U O I K L P Q R S V B C D E

(Thêm kí tự R do thiếu & Thầy SIWTOM đã fát hiện ra)

Ví dụ người gởi viết rất thật lòng:

Thư gởi từ Đồng Tháp Mười:
. . . . . . . . . .

Lúc đó người nhận sẽ dễ tiêu thụ hay thủ tiêu bản mật mã này!

Chúc vui & Rất cảm ơn bạn đã nhiệt tình với loạt bài này!
 
Lần chỉnh sửa cuối:
Upvote 0

BÀI TẬP 4

Trước khi đi vào mã hóa & giải mã dạng bài tập ứng dụng hình vuông Vigenère fức tập nêu trên, xin các bạn thử sức với bài tập sau đây

Ta có bảng chữ cái tiếng Việt như sau

A B C D E G H I K L M N O P Q S T U V X Y
Hình như thiếu "R"

Và dẫy đễ mã hóa có tên là HOASUNG như dưới đây:

H O A S U N G I K L M P Q T V X Y A B C D E

Nếu tôi hiểu được ý thì bảng tra phải là "HOASUNGIKLMPQRTVXYBCDE"

Tức có R (thiếu) và bỏ A ở sau Y

Các bạn hãy mã hóa cụm từ "TRI THUC LA SUC MANH" giúp nha.

Vẫn với đk là các dấu cách thay bằng F, J, W, Z theo chu kỳ như thế

Mã:
Function Encrypt(ByVal text As String, ByVal offset As Long, Optional ByVal bangtra As String = "") As String
'    neu Ma voi offset = a thi Giai Ma voi offset = -a
'    bangtra khong duoc co cac ky tu F, J, W, Z la cac ky tu dung thay cho dau cach - SPACE
'    cac dau cach trong text theo chu ky F, J, W, Z
Const spaces = "FJWZ"
Const default = "ABCDEGHIKLMNOPQRSTUVXY"
Dim tmp As String, k As Long, code As Byte, dic As Object, c As String, pos As Long, c1 As String
    text = UCase(text)
    If bangtra = "" Then bangtra = default
    Set dic = CreateObject("Scripting.Dictionary")
'    cho cac cap ky tu (ky_tu, ky_tu_thay_the) vao tu dien
    For k = 1 To Len(bangtra)
        c = Mid(bangtra, k, 1)
        If Not dic.exists(c) Then dic.Add c, Mid(bangtra, ((k - 1 + offset + Len(bangtra)) Mod Len(bangtra)) + 1, 1)
    Next
'    chuyen tung ky tu thanh ky tu thay the
    For k = 1 To Len(text)
'        doc ky tu
        c = Mid(text, k, 1)
'        neu la dau cach thi thay bang F, J, W hoac Z
        If Asc(c) = 32 Then
            c = Mid(spaces, (pos Mod 4) + 1, 1)
            pos = pos + 1
'        neu la ky tu thay the cho dau cach thi chuyen thanh dau cach
        ElseIf InStr(1, spaces, c) > 0 Then
            c = Chr(32)
'        neu la ky tu trong bangtra thi chuyen thanh ky tu thay the. Neu khong thi de nguyen
        ElseIf dic.exists(c) Then
            c = dic.Item(c)
        End If
        tmp = tmp & c
    Next
    Encrypt = tmp
End Function

Function EncryptWithKey(ByVal text As String, ByVal offset As Long, ByVal key As String) As String
Const bangchu = "ABCDEGHIKLMNOPQRSTUVXY"
Dim k As Long, bangtra As String, c As String, s As String
    key = UCase(key)
    bangtra = key
    s = Mid(bangchu, Len(key) + 1) & Left(bangchu, Len(key))
    For k = 1 To Len(s)
        c = Mid(s, k, 1)
        If InStr(1, key, c) = 0 Then bangtra = bangtra & c
    Next
    
    EncryptWithKey = Encrypt(text, offset, bangtra)
End Function

Sub test()
Dim s As String
    s = EncryptWithKey("TRI THUC LA SUC MANH?", -5, "hoasung")
    Debug.Print s
    s = EncryptWithKey(s, 5, "hoasung")
    Debug.Print s
End Sub

Hàm Encrypt là tổng quát dùng cho bảng tra bất kỳ.
Hàm EncryptWithKey dùng cho trường hợp cụ thể của bạn khi ta có bảng chữ cái cố định từ A-Y và có tên Mã = key
 
Lần chỉnh sửa cuối:
Upvote 0
Mã hóa với việc dùng hình vuông Vigenère tiêu chuẩn

BÀI TẬP SỐ 5

Các bạn giúp tôi mã hóa mệnh đề "TRI THUC LA SUC MANH CUA LOAI NGUOI"
nhờ hình vuông Vigenère có từ khóa là HANOI, như sau:

A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z|A
C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z|A|B
D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z|A|B|C
E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z|A|B|C|D
F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z|A|B|C|D|E
G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z|A|B|C|D|E|F
H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z | A | B | C | D | E | F | G I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z | A | B | C | D | E | F | G | H
J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z|A|B|C|D|E|F|G|H|I
K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z|A|B|C|D|E|F|G|H|I|J
L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z|A|B|C|D|E|F|G|H|I|J|K
M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z|A|B|C|D|E|F|G|H|I|J|K|L
N | O | P | Q | R | S | T | U | V | W | X | Y | Z | A | B | C | D | E | F | G | H | I | J | K | L | M O | P | Q | R | S | T | U | V | W | X | Y | Z | A | B | C | D | E | F | G | H | I | J | K | L | M | N
P|Q|R|S|T|U|V|W|X|Y|Z|A|B|C|D|E|F|G|H|I|J|K|L|M|N|O
Q|R|S|T|U|V|W|X|Y|Z|A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P
R|S|T|U|V|W|X|Y|Z|A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q
S|T|U|V|W|X|Y|Z|A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R
T|U|V|W|X|Y|Z|A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S
U|V|W|X|Y|Z|A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T
V|W|X|Y|Z|A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U
W|X|Y|Z|A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V
X|Y|Z|A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W
Y|Z|A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X
Z|A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y

Ví dụ minh họa: Để mã hóa chữ cái đầu của mệnh đề ('T'), ta xem chữ 'T' của dòng đầu tiên của hình vuông ứng với cột nào của dòng có chữ 'H' ở đầu dòng & lấy nó làm mã; (Đó là chữ 'A')
Tiếp theo ta tra đến chữ thứ nhì là chữ 'R' với dòng đầu tiên của hình vuông (Ở trường hợp này là chính nó luôn: 'R'); (Vì từ thứ 2 trong từ khóa là từ 'A'); Vậy là ta có 2 từ mã hóa của TR sẽ là AR
Từ 'I' của mệnh đề sẽ được tra tại dòng có chữ 'N' ở đầu dòng
. . . . .
 
Lần chỉnh sửa cuối:
Upvote 0
Tôi nhìn đề bài, thấy hai cụm từ "đơn giản" và "xử lý chuỗi" cho nên góp mặt chơi cho vui. Nhưng đến đây thì cao xa quá, chả hiểu gì hết. Đáng lẽ tiêu đề phải là "Những phương thức giải lý công việc mã hoá bằng VBA". Nếu tôi thấy tiêu đề này từ đầu thì đã tự biết phận.

Mục đích tôi đưa code ra là để giới thiệu với các bạn mới học code VBA ở 2 kỹ thuật:

1. Kỹ thuật dùng phép áp 1-1 để chuyển đổi dữ liệu. Trong code của tôi, bạn sẽ thấy người viết không cần phải biết Ascii của "A" là 65 - chỉ cần theo nguyên tắc "B" lớn hơn "A", và "C" lớn hơn "B",...

2. Kỹ thuật dùng chuõi cố định. Trong suốt giai đoạn chuyển mã, code của tôi giữ nguyên cái vỏ của chuỗi s, nó chỉ thay đổi cái ruột (những gì chứa trong chuỗi). Trái với cách dùng thông thường là chuỗi động; toán tử "=" bỏ chuỗi cũ, lập lại một chuỗi mới.
Khác với integer, float,... String (chuỗi) là một loại đối tượng bán phức tạp. Mỗi lần bạn dùng phép gán "=" cho đối tượng đơn giản như integer, hệ thống làm toán và ghi kết quả vào đích, đối tượng vẫn nằm đó, chỉ thay đổi trị. Tuy nhiên với đối tượng phức tạp, phép gán chuỗi ép hệ thống phải bỏ đối tượng cũ và lập mới.
Hàm Mid là một thủ thuật hiệu quả để tránh việc bỏ cũ lập mới này
 
Upvote 0
Mình đoan chắc 1 điều rằng, nhờ vòng lặp với hàm InStr() có thể làm được sất các bạn!

Mình có sẵn các đáp án chỉ vòng lặp, khai báo các Const dạng chuỗi là có thể xử lý được các anh chàng này;

& nhớ thêm 1 điều rằng các mã khoá này đã bị hóa giải từ những thế kỷ 17 lựn đó nha!

Macro chỉ giúp ta hoá mã hay hóa giải nhanh hơn mà thôi.

Mà mình cũng nghỉ tới cách này, dùng hàm VLOOKUP() tra bảng, như chưa thử làm. Vậy nên mới đưa vô BOX lập trình.

Như bài V mình thử gợi í các bạn trình độ sơ cấp nha:

Khai báo 5 hằng số HH, AA, NN, OO, II chứa chuỗi tương ứng;
Tạo vòng lặp duyệt từ đầu chí cuối chuỗi nguồn (cần mã hóa)
Định vị xem từ đang duyệt ở vị trí nào trong chuỗi AA
Xác định xem từ đang xét chia cho 5 (độ dài của từ khóa HANOI) để lấy 1 trong 5 hằng đã khai báo cắt ra 1 kí tự cần thiết cho vô chuỗi kết quả (là tên hàm cần viết)
Có vậy, chỉ cần kiến thức sơ cấp về VBA (chứ không như VietMini nói) có thể làm chiều xuôi được rồi.
Còn chiều ngược lại thì cần đầu tư thêm;

Các bạn đừng choáng ngợp vớ mớ kiến thức về mã hóa mà nản lòng! Đó chẳng qua mình đang đọc cuốn "Mật mã, từ cổ điển đến lượng tử" đem áp dụng trong VBA mà thôi.
Rất mong các bạn tham gia thêm cùng mình!

Thân ái!
 
Lần chỉnh sửa cuối:
Upvote 0
Bài #12 không biết dhn46 hiểu như thế này có đúng hay không:

- Chuỗi cần mã hóa: "TRI THUC LA SUC MANH CUA LOAI NGUOI"
- Chuỗi key: "
HANOI"

Các bước phải làm đó là:

1/ Dựng bảng mã
2/Xây dựng 1 đoạn chuỗi Key mới dựa trên Key cũ lặp đi, lặp lại sao cho có số ký tự bằng chuỗi cần mã hóa
3/ So sánh hàng 1 trong bảng mã với từng ký tự chuỗi cần mã hóa và so sánh cột 1 bảng mã với từng ký tự chuỗi Key mới => Tìm giá trị trùng trên hàng và cột đó gióng theo x,y để lấy giá trị trong bảng mã tương ứng
4/ Với dấu cách thì để nguyên

Nếu đúng như
dhn46 suy luận thì đây là cách xử lý chuỗi cơ bản như đúng tiêu đề bài bác Sa đã viết

Vậy
dhn46 cũng thử 1 code
Mã:
Function Encrypt(ByVal Str As String, ByVal Key As String) As String
    Const Default = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    Dim k As Long
    Dim Bangma(1 To 26, 1 To 26)
    Dim sArr()
    ReDim sArr(1 To Len(Str), 1 To 2)
    'Dua du lieu vao bang ma
    For i = 1 To 26
        For j = 1 To 26
            If k = 26 Then
                k = 1
            Else
                k = k + 1
            End If
            Bangma(i, j) = Mid(Default, k, 1)
        Next
        k = i
    Next
    'Tao NKey co do dai bang do dai Str
    If Len(Str) > Len(Key) Then
        For i = 1 To Int(Len(Str) / Len(Key))
            NKey = NKey & Key
        Next
        NKey = NKey & Left(Key, Len(Str) - Int(Len(Str) / Len(Key)) * Len(Key))
    End If
    'Tim theo truc x
    For k = 1 To Len(Str)
        For i = 1 To 26
            If UCase(Bangma(1, i)) = UCase(Mid(Str, k, 1)) Then
                sArr(k, 1) = i
                Exit For
            Else
                sArr(k, 1) = ""
            End If
        Next
    Next
    'Tim theo truc y
    For k = 1 To Len(NKey)
        For j = 1 To 26
            If UCase(Bangma(j, 1)) = UCase(Mid(NKey, k, 1)) Then
                sArr(k, 2) = j
            End If
        Next
    Next
    For k = 1 To Len(Str)
        If sArr(k, 1) <> "" Then
            Encrypt = Encrypt & Bangma(sArr(k, 1), sArr(k, 2))
        Else
            Encrypt = Encrypt & " "
        End If
    Next
End Function


Sub Test()
    Dim Str As String, Key As String, s As String
    Str = "TRI THUC LA SUC MANH CUA LOAI NGUOI"
    Key = "HANOI"
    s = Encrypt(Str, Key)
    Debug.Print s
End Sub



 
Upvote 0
Trong hình vuông Vigenère ta có tất cả 26 dòng;
Với từ khóa là HANOI ta chì lấy 5 dòng làm chuẩn để so; 5 dòng này là 5 dòng có các kí tự đứng đầu dòng trùng với từ khóa H-A-N-O-I nêu trên;

Sau đó ta duyệt lần lượt từng ký tự của mệnh đề cần mã hóa (TRI THUC LÀ SUC MANH CUA LOAI NGUOI)
Kí tự đầu tiên so với dòng chuẩn đầu tiên; Dòng chuẩn này là dòng có chứa kí tự 'H' đầu tiên

Cụ thể dòng góc
A B C D E F G H I J K L M N O P Q R S T U (T ở vị trí 20)
Ta lấy kí tự thứ 20 của dòng chuần 'H' thay vô, làm mã thay thế cho 'T'
đó là H I J K L M N O P Q R S T U V W X Y Z A B C . . .

Vậy là ta đã mã hóa được kí tự T bằng ký tự A

Với kí tự R tiếp theo, ta không lấy dòng [H] làm chuẩn nữa, mà lầy dòng chuẩn có ký tự đầu là 'A' (đó cũng chính là dòng góc)
Thì lúc này R vẫn được mã hóa thành R mà thôi!
Với kí tự thứ 3 'I' ta thấy 'I' trong dòng góc A B C . . . nó đứng thứ 9; ta fải lấy kí tự thứ 9 của dòng chuẩn [N. . .] thay cho kí tự 'I'
. . . .
 
Lần chỉnh sửa cuối:
Upvote 0
Mạo muội tham gia một đáp án sau:

Mã:
Dim Arr(1 To 26, 1 To 26), R As Long, C As Long
Sub Vigenere()
    For C = 1 To 26
        For R = 1 To 26
            ii = R + C - 1
            Arr(R, C) = Chr(ii - 26 * (ii \ 27) + 64)
        Next
    Next
    ' Range("A1").Resize(26, 26) = Arr
End Sub
Function Encrypt(ByVal MyStr As String, ByVal Key As String) As String
    Dim i As Long, Char1 As String, Char2 As String
    Call Vigenere
    For i = 1 To Len(MyStr)
        Char1 = UCase(Mid(MyStr, i, 1))
        If Char1 <> " " Then
            Char2 = Mid(Key, i - Len(Key) * ((i - 1) \ Len(Key)), 1)
        Else
            Encrypt = Encrypt & Char1
        End If
        For C = 1 To 26
            For R = 1 To 26
                If Arr(R, 1) = Char2 And Arr(1, C) = Char1 Then
                    Encrypt = Encrypt & Arr(R, C)
                End If
            Next
        Next
    Next
End Function
Sub Test()
    MsgBox Encrypt("TRI THUC LA SUC MANH CUA LOAI NGUOI", "HANOI")
End Sub
Mã hóa xong ta được chuỗi mới là: "ARV BOUP TH FIK MNBP CHO SONW UGHCQ"

Code giải mã cũng tương tự (cùng trong một module)

Mã:
Function UnEncrypt(ByVal MyStr As String, ByVal Key As String) As String
    Dim i As Long, Char1 As String, Char2 As String
    Call Vigenere
    For i = 1 To Len(MyStr)
        Char1 = UCase(Mid(MyStr, i, 1))
        If Char1 <> " " Then
            Char2 = Mid(Key, i - Len(Key) * ((i - 1) \ Len(Key)), 1)
        Else
            UnEncrypt = UnEncrypt & Char1
        End If
        For C = 1 To 26
            For R = 1 To 26
                If Arr(R, 1) = Char2 And Arr(R, C) = Char1 Then
                    UnEncrypt = UnEncrypt & Arr(1, C)
                End If
            Next
        Next
    Next
End Function
Sub Test2()
    Debug.Print UnEncrypt("ARV BOUP TH FIK MNBP CHO SONW UGHCQ", "HANOI")
End Sub
 
Lần chỉnh sửa cuối:
Upvote 0
Với mật khẩu 'DONGTHAPMUOI' mình có hàm sau:

PHP:
Option Explicit
Function DongThapMuoi(StrC As String) As String
 ReDim Arr(1 To 12) As String
 Dim J As Integer, VTr As Byte, W As Byte
 
 Arr(1) = "DEFGHIJKLMNOPQRSTUVWXYZABC"      'D'
 Arr(2) = "OPQRSTUVWXYZABCDEFGHIJKLMN"  'O'
 Arr(3) = "NOPQRSTUVWXYZABCDEFGHIJKLM"  'N'
 Arr(4) = "GHIJKLMNOPQRSTUVWXYZABCDEF"  'G'
 Arr(5) = "TUVWXYZABCDEFGHIJKLMNOPQRS"  'T'
 Arr(6) = "HIJKLMNOPQRSTUVWXYZABCDEFG"  'H'
 Arr(7) = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"  'A'
 Arr(8) = "PQRSTUVWXYZABCDEFGHIJKLMNO"  'P'
 Arr(9) = "MNOPQRSTUVWXYZABCDEFGHIJKL"  'M'
 Arr(10) = "UVWXYZABCDEFGHIJKLMNOPQRST"  'U'
 Arr(11) = "OPQRSTUVWXYZABCDEFGHIJKLMN"  'O'
 Arr(12) = "IJKLMNOPQRSTUVWXYZABCDEFGH"  'I'
 
 For J = 1 To Len(StrC)
    VTr = InStr(Arr(7), Mid(StrC, J, 1))
    If VTr Then
        W = J Mod (Len("DongThapMuoi"))
        If W = 0 Then W = Len("DongThapMuoi")
        DongThapMuoi = DongThapMuoi & Mid(Arr(W), VTr, 1)
    Else
        DongThapMuoi = DongThapMuoi & " "
    End If
 Next J
End Function
 
Chỉnh sửa lần cuối bởi điều hành viên:
Upvote 0
Với đề bài 1, các bạn trình độ sơ cấp VBA có thể viết vầy

PHP:
Function MaHoa5(StrC As String, Optional Thuan As Boolean = True) As String
 Const Alf As String = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
 Const Khoa As String = "VWXYZ" & Alf
 Dim J As Long, I As Long, VTr As Long

 For J = 1 To Len(StrC)
    VTr = InStr(IIf(Thuan, Alf, Khoa), Mid(StrC, J, 1))
    If VTr > 0 Then
        MaHoa5 = MaHoa5 & Mid(IIf(Thuan, Khoa, Alf), VTr, 1)
    Else
        MaHoa5 = MaHoa5 & " "
    End If
 Next J
End Function
 
Upvote 0
(Bài tập dành cho các bạn sơ trung cấp VBA)

BÀI 5A


Hãy viết hàm mã hóa & giãi mã mệnh đề nào đó với từ khóa là 'STOP' áp dụng cho hình vuông bên trên;




Các bạn có thể tham khảo hàm sau:

PHP:
Option Explicit
Function DongThapMuoi(StrC As String, Optional Thuan As Boolean = True) As String
 ReDim Arr(1 To 12) As String
 Dim J As Integer, VTr As Byte, W As Byte
 
 Arr(1) = "DEFGHIJKLMNOPQRSTUVWXYZABC"   'D'
 Arr(2) = "OPQRSTUVWXYZABCDEFGHIJKLMN"  'O'
 Arr(3) = "NOPQRSTUVWXYZABCDEFGHIJKLM"  'N'
 Arr(4) = "GHIJKLMNOPQRSTUVWXYZABCDEF"  'G'
 Arr(5) = "TUVWXYZABCDEFGHIJKLMNOPQRS"  'T'
 Arr(6) = "HIJKLMNOPQRSTUVWXYZABCDEFG"  'H'
 Arr(7) = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"  'A'
 Arr(8) = "PQRSTUVWXYZABCDEFGHIJKLMNO"  'P'
 Arr(9) = "MNOPQRSTUVWXYZABCDEFGHIJKL"  'M'
 Arr(10) = "UVWXYZABCDEFGHIJKLMNOPQRST"  'U'
 Arr(11) = "OPQRSTUVWXYZABCDEFGHIJKLMN"  'O'
 Arr(12) = "IJKLMNOPQRSTUVWXYZABCDEFGH"  'I'
 
 For J = 1 To Len(StrC)
    If Thuan Then
        VTr = InStr(Arr(7), Mid(StrC, J, 1))
    Else
        W = J Mod (Len("DongThapMuoi"))
        If W = 0 Then W = Len("DongThapMuoi")
        VTr = InStr(Arr(W), Mid(StrC, J, 1))
    End If
    If VTr Then
        If Thuan Then
            W = J Mod (Len("DongThapMuoi"))
            If W = 0 Then W = Len("DongThapMuoi")
            DongThapMuoi = DongThapMuoi & Mid(Arr(W), VTr, 1)
        Else
            DongThapMuoi = DongThapMuoi & Mid(Arr(7), VTr, 1)
        End If
    Else
        DongThapMuoi = DongThapMuoi & " "
    End If
 Next J
End Function
 
Lần chỉnh sửa cuối:
Upvote 0
Một cách khác

BÀI TẬP SỐ 5

Các bạn giúp tôi mã hóa mệnh đề "TRI THUC LA SUC MANH CUA LOAI NGUOI"
nhờ hình vuông Vigenère có từ khóa là HANOI, như sau:

...

Ví dụ minh họa: Để mã hóa chữ cái đầu của mệnh đề ('T'), ta xem chữ 'T' của dòng đầu tiên của hình vuông ứng với cột nào của dòng có chữ 'H' ở đầu dòng & lấy nó làm mã; (Đó là chữ 'A')
Tiếp theo ta tra đến chữ thứ nhì là chữ 'R' với dòng đầu tiên của hình vuông (Ở trường hợp này là chính nó luôn: 'R'); (Vì từ thứ 2 trong từ khóa là từ 'A'); Vậy là ta có 2 từ mã hóa của TR sẽ là AR
Từ 'I' của mệnh đề sẽ được tra tại dòng có chữ 'N' ở đầu dòng
. . . . .
Hàm mã hóa
PHP:
Function MaHoa(MyStr As String, Key As String) As String
Dim i As Long
Const Str = "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXY "
For i = 1 To Len(MyStr)
    MaHoa = MaHoa & IIf(Mid(MyStr, i, 1) = " ", " ", Mid(Str, InStr(Str, Mid(Key, ((i - 1) Mod Len(Key)) + 1, 1)) + InStr(Str, Mid(MyStr, i, 1)) - 1, 1))
Next
End Function
Hàm giải mã
PHP:
Function GiaiMa(MyStr As String, Key As String) As String
Dim i As Long
Const Str = "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXY "
For i = 1 To Len(MyStr)
    GiaiMa = GiaiMa & IIf(Mid(MyStr, i, 1) = " ", " ", Mid(Str, InStr(InStr(Str, Mid(Key, ((i - 1) Mod Len(Key)) + 1, 1)), Str, Mid(MyStr, i, 1)) - InStr(Str, Mid(Key, ((i - 1) Mod Len(Key)) + 1, 1)) + 1, 1))
Next
End Function
 
Upvote 0
BÀI 5A
Hãy viết hàm mã hóa & giãi mã mệnh đề nào đó với từ khóa là 'STOP' áp dụng cho hình vuông bên trên;Các bạn có thể tham khảo hàm sau:
PHP:
Option ExplicitFunction DongThapMuoi(StrC As String, Optional Thuan As Boolean = True) As String ReDim Arr(1 To 12) As String Dim J As Integer, VTr As Byte, W As Byte  Arr(1) = "DEFGHIJKLMNOPQSTUVWXYZABC"   'D' Arr(2) = "OPQRSTUVWXYZABCDEFGHIJKLMN"  'O' Arr(3) = "NOPQRSTUVWXYZABCDEFGHIJKLM"  'N' Arr(4) = "GHIJKLMNOPQRSTUVWXYZABCDEF"  'G' Arr(5) = "TUVWXYZABCDEFGHIJKLMNOPQRS"  'T' Arr(6) = "HIJKLMNOPQRSTUVWXYZABCDEFG"  'H' Arr(7) = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"  'A' Arr(8) = "PQRSTUVWXYZABCDEFGHIJKLMNO"  'P' Arr(9) = "MNOPQRSTUVWXYZABCDEFGHIJKL"  'M' Arr(10) = "UVWXYZABCDEFGHIJKLMNOPQRST"  'U' Arr(11) = "OPQRSTUVWXYZABCDEFGHIJKLMN"  'O' Arr(12) = "IJKLMNOPQRSTUVWXYZABCDEFGH"  'I'  For J = 1 To Len(StrC)    If Thuan Then        VTr = InStr(Arr(7), Mid(StrC, J, 1))    Else        W = J Mod (Len("DongThapMuoi"))        If W = 0 Then W = Len("DongThapMuoi")        VTr = InStr(Arr(W), Mid(StrC, J, 1))    End If    If VTr Then        If Thuan Then            W = J Mod (Len("DongThapMuoi"))            If W = 0 Then W = Len("DongThapMuoi")            DongThapMuoi = DongThapMuoi & Mid(Arr(W), VTr, 1)        Else            DongThapMuoi = DongThapMuoi & Mid(Arr(7), VTr, 1)        End If    Else        DongThapMuoi = DongThapMuoi & " "    End If Next JEnd Function
Mình gộp code mã hoá và giải mã của mình lại là được code sau:
Mã:
Option ExplicitDim Arr(1 To 26, 1 To 26), R As Long, C As LongSub Vigenere()    Dim ii As Long    For C = 1 To 26        For R = 1 To 26            ii = R + C - 1            Arr(R, C) = Chr(ii - 26 * (ii \ 27) + 64)        Next    NextEnd SubFunction Encrypt(ByVal MyStr As String, ByVal Key As String, Optional Thuan As Boolean = True) As String    Dim i As Long, Char1 As String, Char2 As String, Ox As String, XY As String    Call Vigenere    For i = 1 To Len(MyStr)        Char1 = UCase(Mid(MyStr, i, 1))        If Char1  " " Then            Char2 = UCase(Mid(Key, i - Len(Key) * ((i - 1) \ Len(Key)), 1))        Else            Encrypt = Encrypt & Char1        End If        For C = 1 To 26            For R = 1 To 26                If Thuan Then                    If Arr(R, 1) = Char2 And Arr(1, C) = Char1 Then Encrypt = Encrypt & Arr(R, C)                Else                    If Arr(R, 1) = Char2 And Arr(R, C) = Char1 Then Encrypt = Encrypt & Arr(1, C)                End If            Next        Next    NextEnd Function
Kiểm tra xem:
Mã:
Sub Test()    Dim Encrypted As String    Encrypted = Encrypt("TRI THUC LA SUC MANH CUA LOAI NGUOI", "DongThapMuoi")    Debug.Print Encrypted    Debug.Print Encrypt(Encrypted, "DongThapMuoi", False)End Sub
Code Anh đưa tham khảo sao mã hóa chữ T đầu tiên thành chữ X nhỉ? lẽ ra phải là chữ W mới đúng?
 
Upvote 0
Bài trên bị lỗi mạng? Không hiểu sao như vậy. Nhờ Mod xóa. May là copy lại được nguyên văn, gởi lại:

BÀI 5A


Hãy viết hàm mã hóa & giãi mã mệnh đề nào đó với từ khóa là 'STOP' áp dụng cho hình vuông bên trên;




Các bạn có thể tham khảo hàm sau:

PHP:
Option Explicit
Function DongThapMuoi(StrC As String, Optional Thuan As Boolean = True) As String
 ReDim Arr(1 To 12) As String
 Dim J As Integer, VTr As Byte, W As Byte
 
 Arr(1) = "DEFGHIJKLMNOPQSTUVWXYZABC"   'D'
 Arr(2) = "OPQRSTUVWXYZABCDEFGHIJKLMN"  'O'
 Arr(3) = "NOPQRSTUVWXYZABCDEFGHIJKLM"  'N'
 Arr(4) = "GHIJKLMNOPQRSTUVWXYZABCDEF"  'G'
 Arr(5) = "TUVWXYZABCDEFGHIJKLMNOPQRS"  'T'
 Arr(6) = "HIJKLMNOPQRSTUVWXYZABCDEFG"  'H'
 Arr(7) = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"  'A'
 Arr(8) = "PQRSTUVWXYZABCDEFGHIJKLMNO"  'P'
 Arr(9) = "MNOPQRSTUVWXYZABCDEFGHIJKL"  'M'
 Arr(10) = "UVWXYZABCDEFGHIJKLMNOPQRST"  'U'
 Arr(11) = "OPQRSTUVWXYZABCDEFGHIJKLMN"  'O'
 Arr(12) = "IJKLMNOPQRSTUVWXYZABCDEFGH"  'I'
 
 For J = 1 To Len(StrC)
    If Thuan Then
        VTr = InStr(Arr(7), Mid(StrC, J, 1))
    Else
        W = J Mod (Len("DongThapMuoi"))
        If W = 0 Then W = Len("DongThapMuoi")
        VTr = InStr(Arr(W), Mid(StrC, J, 1))
    End If
    If VTr Then
        If Thuan Then
            W = J Mod (Len("DongThapMuoi"))
            If W = 0 Then W = Len("DongThapMuoi")
            DongThapMuoi = DongThapMuoi & Mid(Arr(W), VTr, 1)
        Else
            DongThapMuoi = DongThapMuoi & Mid(Arr(7), VTr, 1)
        End If
    Else
        DongThapMuoi = DongThapMuoi & " "
    End If
 Next J
End Function

Mình gộp code mã hoá và giải mã của mình lại là được code sau:

Mã:
Option Explicit
Dim Arr(1 To 26, 1 To 26), R As Long, C As Long
Sub Vigenere()
    Dim ii As Long
    For C = 1 To 26
        For R = 1 To 26
            ii = R + C - 1
            Arr(R, C) = Chr(ii - 26 * (ii \ 27) + 64)
        Next
    Next
End Sub
Function Encrypt(ByVal MyStr As String, ByVal Key As String, Optional Thuan As Boolean = True) As String
    Dim i As Long, Char1 As String, Char2 As String, Ox As String, XY As String
    Call Vigenere
    For i = 1 To Len(MyStr)
        Char1 = UCase(Mid(MyStr, i, 1))
        If Char1 <> " " Then
            Char2 = UCase(Mid(Key, i - Len(Key) * ((i - 1) \ Len(Key)), 1))
        Else
            Encrypt = Encrypt & Char1
        End If
        For C = 1 To 26
            For R = 1 To 26
                If Thuan Then
                    If Arr(R, 1) = Char2 And Arr(1, C) = Char1 Then Encrypt = Encrypt & Arr(R, C)
                Else
                    If Arr(R, 1) = Char2 And Arr(R, C) = Char1 Then Encrypt = Encrypt & Arr(1, C)
                End If
            Next
        Next
    Next
End Function

Kiểm tra xem:
Mã:
Sub Test()
    Dim Encrypted As String
    Encrypted = Encrypt("TRI THUC LA SUC MANH CUA LOAI NGUOI", "DongThapMuoi")
    Debug.Print Encrypted
    Debug.Print Encrypt(Encrypted, "DongThapMuoi", False)
End Sub

Code Anh đưa tham khảo sao mã hóa chữ T đầu tiên thành chữ X nhỉ? lẽ ra phải là chữ W mới đúng?
 
Upvote 0
Code Anh đưa tham khảo sao mã hóa chữ T đầu tiên thành chữ X nhỉ? lẽ ra phải là chữ W mới đúng?

Đúng rồi! Mình sai là do Arr(1) thiếu 1 kí tự, đó là 'R'


Mình thử đưa từ khóa vô hàm luôn:

PHP:
Option Explicit
Function NghiaLo(StrC As String, TuKhoa As String, Optional Thuan As Boolean = True) As String
 Const Alf As String = "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ"
 ReDim Arr(1 To Len(TuKhoa))
 Dim J As Integer, VTr As Byte, W As Byte
 
 TuKhoa = UCase$(TuKhoa)
 For J = 1 To Len(TuKhoa)
    Arr(J) = InStr(Alf, Mid(TuKhoa, J, 1))
 Next J
 For J = 1 To Len(StrC)
    If Thuan Then
        VTr = InStr(Alf, Mid(StrC, J, 1))
    Else
        W = J Mod (Len(TuKhoa))
        If W = 0 Then W = Len(TuKhoa)
        VTr = InStr(Mid(Alf, Arr(W), 26), Mid(StrC, J, 1))
    End If
    If VTr Then
        If Thuan Then
            W = J Mod (Len(TuKhoa))
            If W = 0 Then W = Len(TuKhoa)
            NghiaLo = NghiaLo & Mid(Mid(Alf, Arr(W), 26), VTr, 1)
        Else
            NghiaLo = NghiaLo & Mid(Alf, VTr, 1)
        End If
    Else
        NghiaLo = NghiaLo & " "
    End If
 Next J
End Function
 
Lần chỉnh sửa cuối:
Upvote 0
BÀI 5A


Hãy viết hàm mã hóa & giãi mã mệnh đề nào đó với từ khóa là 'STOP' áp dụng cho hình vuông bên trên;

Đề xuất tăng độ khó:

Theo đề trên, cột chứa các ký tự của mật mã nằm ở cột thứ nhất, dòng chứa các ký tự của chuỗi cần mã hóa là ở dòng thứ nhất, còn các ký tự được mã hóa là giao điểm của dòng và cột đó.
Đúng không Anh?

Bây giờ mình đề xuất cột chứa các ký tự của mật mã và dòng chứa các ký tự của chuỗi cần mã hóa là bất kỳ: X, Y với X, Y là số nguyên và thuộc [1, 26]. Viết hàm để mã hóa và giải mã như trên nhưng có thêm hai tham số X và Y.
Hàm có dạng Mahoa(Chuỗi, khóa, X, Y, tùy chọn khóa hoặc mở).
Xin mời các bạn có trình độ sơ cấp và ..... mình.
 
Upvote 0
Chuyện này chỉ tăng tính học thuật thôi; Trong thực tế ứng dụng sẽ khó hơn.

[thongbao]Bây giờ mình đề xuất cột chứa các ký tự của mật mã và dòng chứa các ký tự của chuỗi cần mã hóa là bất kỳ: X, Y với X, Y là số nguyên và thuộc [1, 26]. Viết hàm để mã hóa và giải mã như trên nhưng có thêm hai tham số X và Y.
Hàm có dạng Mahoa(Chuỗi, khóa, X, Y, tùy chọn khóa hoặc mở).
[/thongbao]

Mình nhất trí với bạn; Nhưng ta nên viết hàm

= MaHoa(Chuỗi, khóa, X, Optional Y=1, tùy chọn khóa hoặc mở)

Sau đó mới tiến dần đến 2 tham số X & Y đều biến thiên.

Bạn nghỉ sao?
 
Upvote 0
[thongbao]Bây giờ mình đề xuất cột chứa các ký tự của mật mã và dòng chứa các ký tự của chuỗi cần mã hóa là bất kỳ: X, Y với X, Y là số nguyên và thuộc [1, 26]. Viết hàm để mã hóa và giải mã như trên nhưng có thêm hai tham số X và Y.
Hàm có dạng Mahoa(Chuỗi, khóa, X, Y, tùy chọn khóa hoặc mở).
[/thongbao]

Mình nhất trí với bạn; Nhưng ta nên viết hàm

= MaHoa(Chuỗi, khóa, X, Optional Y=1, tùy chọn khóa hoặc mở)

Sau đó mới tiến dần đến 2 tham số X & Y đều biến thiên.

Bạn nghỉ sao?

Ok! Xin mời các bạn giải.

-------------------------------------------------------------------------------------------------
Đúng là tính học thuật có tăng lên, nhưng tính bảo mật cũng tăng: Lỡ "lộ" khóa thì "đối phương" khó mò ra hơn, giả sử là họ biết cách giải, biết khóa, nhưng không biết X, Y cũng tốn nhiều thời gian vì phải xét 26^2 trường hợp!
 
Lần chỉnh sửa cuối:
Upvote 0
Ok! Xin mời các bạn giải.

-------------------------------------------------------------------------------------------------
Đúng là tính học thuật có tăng lên, nhưng tính bảo mật cũng tăng: Lỡ "lộ" khóa thì "đối phương" khó mò ra hơn, giả sử là họ biết cách giải, biết khóa, nhưng không biết X, Y cũng tốn nhiều thời gian vì phải xét 26^2 trường hợp!


Bổ sung: Hướng dẫn cho bạn nào chưa hiểu đề.
Xin được thay mặt "chị" HYen17 giải thích lại cách mã hóa như sau:

Giả sử ta có chuỗi cần mã hóa là: "TRI THUC LA SUC MANH CUA CUOC SONG", khóa là "LAODONG", X=10, Y=1

Bạn xếp khóa vào chuỗi như sau:

123 4567 8.....
TRI THUC LA SUC MANH CUA CUOC SONG
LAO DONG LA ODO NGLA ODO NGLA ODON

Dựa vào hình vuông Vigenere, Bạn mã hóa cho tất cả các ký tự của chuỗi.

Ký đầu tiên là T, có khóa là L.
Bạn tìm trên dòng đầu tiên (Y=1), tìm chữ T -> Được cột cần tìm chứa chữ T.
Tiếp theo tìm cột thứ 10 (X=10), tìm chữ L -> được dòng cần tìm chứa khóa L
Giao điểm của dòng cần tìm và cột cần tìm là ký tự V cần tìm.
Vậy chữ T đầu tiên được mã hóa thành chữ V.

Tương tự cho tất cả các chữ khác của chuỗi cần tìm.
 
Upvote 0
Xin giới thiêu với các bạn mật mã ADFGVX

Các bài trước bài này, chúng ta nghiên cứu để làm ra những mật mã khác nhau, nhưng tựu chung chúng vẫn là loại mật mã thay thế. (Có nghĩa là dùng 1 hay 2 kí tự để thay cho 1 ký tự cần truyền tin)

Loại mật mã này chỉ fổ dụng nhiều thế kỷ trước đại chiến thứ II mà thôi; Chứ sau những năm 30 của thế kỷ trước thì đã bị hóa giải hầu hết, không chống thì chày!
(Còn hóa giải như thế nào, thì ở đây chúng ta khoan bàn tới)
Để lập ra loại mật mã khó hơn đảm bảo thuận tiện & an toàn hơn, người đời đã nghĩ ra hình vuông ADFGVX

Hình vuông này đã được mình chế tác khác nguyên bản 1 chút, như sau:

| A | D | F | G | V | X A |1|A|B|C|D|6
D |2|E|F|G|H|7
F |3|I |J|K|L|8
G |4|M|N|O|P|9
V |5|Q|R| S|T|0
X |U|V|W|X|Y|Z
Thứ tụ sắp xếp trong các ô hàng ngày cũng đóng vai trò là 1 fần của chìa khóa tạo nên mật mã; Nhưng nếu như vậy thì chưa có gì là ghê gớm & rất dễ bị bẽ khóa. Cái ghê gớm đang nằm ở fía sau (Các bạn chịu khó chờ chút nha)

Nhiệm vụ của điện báo viên (ĐBV) là mã hóa đoạn lênh quan trọng: "Tan cong luc 8h30 toi mai"

Bước 1:
Lấy từng chữ cái trong bức điện trên, xác định xem đầu hàng & đầu cột của nó là 2 kí tự gì;
Ví dụ: Chữ 'T' có đầu hàng là chữ 'V' & đầu cột cũng là chữ 'V'
Con số '8' có đầu hàng là chữ 'F' & đầu cột là chữ 'X'
Chữ 'a' có đầu hàng là chữ 'A' & đầu cột là chữ 'D'
. . . . . .

Ta thay chữ 'T' trong mệnh đề bằng cặp đôi VV; chữ 'a' bằng cặp đôi AD,. . . (Như vậy con số '8':=FX

Như vậy mật mã sau bước 1 sẽ là: VV AD. . . . FX. . . . .

Bước 2 :
Ta chọn từ khoá là HOABINH để xếp tất cả các nhóm từ đã mã hóa ở bước 1 vô hình vuông mới:

H|O|A|B|I|N|H
O|V|V|A|D|.|.
A|..|.|..|..|.|.
B|..|.|..|..|.|.
I|..|.|..|..|.|.
N|..|.|F|X|.|.
H|..|.|..|..|.|.
Nếu dừng ở đây thì không có gì để nói;
Nhưng để chống trộm, người ta đã (dùng excel?) để xếp bảng thứ 2 này theo cột đầu
Sau khi xếp xong trừ hàng tiêu đề, hàng có dòng 'A' đang là thứ 3 sẽ chuyển lên thành dòng thứ 2

Người ĐBV chỉ truyền đi các từ mooc xơ quanh đi quẫn lại có 5 từ trong bảng thứ 3 này mà thôi
Tất nhiên các bạn có thể hiểu là tại sao người ta chọn các từ ADFGVX, mà không chọn các từ khác rồi chứ?
 
Lần chỉnh sửa cuối:
Upvote 0
Bài này đơn giản nè các bạn:

BÀI TẬP 7

Các bạn viết giúp cho người điện tín viên bước 1 đoạn mã hóa của mệnh đề "Tan cong luc 8H30 toi mai."
theo gợi í của file kèm theo
 

File đính kèm

Upvote 0
Một cách đơn giản để giải bài #7

Mã:
Option Explicit
[B]Sub GPE()
[/B]Dim Rng As Range, Cls As Range
 Dim StrC As String, SMa As String
 Dim J As Long
 [COLOR=#0000cd]'Xác Dinh Vùng Khoá Ma Buóc 1:'[/COLOR]
 Set Rng = [b2].CurrentRegion
[COLOR=#0000cd]'Chuyen Menh Dè Càn Ma Hóa Vo Bién:'
[/COLOR]StrC = [i1].Value
[COLOR=#0000cd]'Nhan Chuoi Ma Hoá Buóc I:'
[/COLOR]SMa = MaHoaADFGVX1(Rng, StrC)
[COLOR=#0000cd]'Fan Fói Chuoi Da Ma Hoá Len Vùng Hien Thi Két Qua:'[/COLOR]
 For Each Cls In Range("B13:g19")
    J = J + 1
    Cls.Value = Mid(SMa, J, 1)
 Next Cls
[B]End Sub
[/B]

PHP:
Function MaHoaADFGVX1(Rng As Range, StrC As String) As String
 Dim sRng As Range:                 Dim J As Integer
     
 StrC = UCase$(StrC)                '*'
 'Loai Bót, Chi Láy Vùng Chúa Du Lieu 6x6=36 O:'
 If Rng.Rows.Count > 6 Then Set Rng = Rng(1).Offset(1, 1).Resize(6, 6)
 'Tao Vòng Lap Duyet Tùng Ký Tu Trong Chuoi Càn Ma Hóa:'
 For J = 1 To Len(StrC)
    'Tìm Dia Chi Dang Chúa Ký Tu Ma Hóa Dang Duyet:'
    Set sRng = Rng.Find(Mid(StrC, J, 1), , xlValues, xlWhole)
    'Khi Tìm Tháy, Ta Láy Tù Dàu Dong & Tù Dàu Cot Dua Vo Chuoi Két Qua Ma Hóa:'
    If Not sRng Is Nothing Then
        MaHoaADFGVX1 = MaHoaADFGVX1 & Cells(sRng.Row, "A").Value & Cells(1, sRng.Column).Value
    End If
 Next J
End Function
 
Upvote 0
Bài đọc thêm

MÃ HÓA TIẾNG VIỆT THÀNH CÁC CHUỖI SỐ


Tiếng Việt của chúng ta gồm những từ đơn, độ dài tối đa là 7 kí tự;
Sau đây mình sẽ tiến hành thử mã hóa, chuyển sang chuỗi các số biểu diễn những mệnh đề tiếng Việt không dấu, như:

Chuỗi “Ho Chi Minh” sẽ chuyển thành “57 33 18 411 512 “

Trong đó từ “Ho” được biểu diễn thàng số 57; Từ “Chi” được biểu diễn bằng chuỗi số “33 18”; , , , ,
Có nghĩa là mình đã ghép đôi 2 kí tự thành 1 nhóm & mỗi nhóm có 1 số gồm 2 hay 3 chữ số biểu diễn chúng. (Ví dụ: từ “Minh” tách thành 2 nhóm; Nhóm đầu được biểu diễn bằng chuỗi số 411;. . )

Để thực hiện điều này trên exxcel, ta cần lấy 1 vùng trang tính & lập bảng như sau:

|A|B|C|D|E|G|. . . |Y
|1|2|3|4|5|6|. . |22
1|A||C||E|G|. . .|Y
2|AI|BA|CA|DA|EI|GA|..|YA
3|AM|BE|CH|DD|EM|GE|..|YE
4|AN|BI|CI|DE|EN|GH|..|YI
5|AO|BO|CO|DI|EO|GI|..|YO
6|AU|BU|CU|DO|ET|GO|..|YU
7|AY|BY|CY|DU|EU|GU|..|YZ
8|AJ||CF|DY|EY|GZ|..|
9|||CW|.|.|.|..|

Sau khi lập bảng như vậy, ta gán tên vùng này là ‘Alf’

Tiếp theo đó ta viết 1 hàm người dùng đơn giản để chuyển các từ cần dịch sang chuỗi số tương ứng;
Hàm này có nội dung như sau:

PHP:
Option Explicit
Function MaHoa(StrC As String)
 Dim Rng As Range, sRng As Range
 Dim J As Byte, VTr As Byte
 Const KT As String = " ":                      Dim Tmp  As String
 
 Set Rng = Range("Alf")
 StrC = UCase$(Trim(StrC)) & KT
 Do
    VTr = InStr(StrC, KT):                      If VTr < 1 Then Exit Do
    Tmp = Trim(Left(StrC, VTr - 1)):            StrC = Mid(StrC, VTr + 1, 99)
    For J = 1 To Len(Tmp) Step 2
        Set sRng = Rng.Find(Trim(Mid(Tmp, J, 2)), , xlFormulas, xlWhole)
        If Not sRng Is Nothing Then
            MaHoa = MaHoa & Cells(sRng.Row, "A").Value & Cells(2, sRng.Column).Value & KT
        End If
    Next J
 Loop

Cách sử dụng:
Tại 1 ô trống nào đó trên trang tính ta nhập mệnh đề cần mã hóa như “Cong Hoa Xa Hoi Chu Nghia Viet Nam”

Tại 1 ô trống khác ta nhập cú fáp hàm =MaHoa(B14)

‘B14’ là ô đang chứa dữ liệu cần mã hóa; & sau khi {ENTER} ta sẽ nhận được chuỗi số sau:

“53 412 57 11 221 57 18 33 119 412 47 11 420 65 212 111”

;;;;;;;;;;; ;;;;;;;;;;; ;;;;;;;;;;;
Đã có hàm mã hóa, ta cũng cần có hàm giải mã; Nó có nội dung như sau:

PHP:
Function GiaiMa(StrC As String)
 Const KT As String = " ":                      Dim Tmp  As String
 Dim J As Byte, VTr As Byte, Dg As Integer, Col As Byte
 Dim Rng As Range
 
 StrC = UCase$(Trim(StrC)) & KT:                Set Rng = Range("Alf")
 Do
    VTr = InStr(StrC, KT):                      If VTr < 1 Then Exit Do
    Tmp = Trim(Left(StrC, VTr - 1)):            StrC = Mid(StrC, VTr + 1, 99)
    Dg = CInt(Left(Tmp, 1)):                    Col = CByte(Mid(Tmp, 2, 2))
    GiaiMa = GiaiMa & Rng(1).Offset(Dg, Col - 1).Value & KT
 Loop
End Function

Khác với các hàm trên, hàm chuyển thành mã & hàm giải mã có thể nhốt chung trong 1; Thì ở đây, ta fải
Xài 2 giải thuật khác nhau, nên viết chung trong 1 hàm sẽ khó hơn nhiều.


Chúc các bạn vui vẻ!
 
Upvote 0

Bài viết mới nhất

Back
Top Bottom