Mã hóa dãy số dài thành chuỗi ngắn (1 người xem)

Liên hệ QC

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

phạm quyên

Thành viên mới
Tham gia
3/5/11
Bài viết
29
Được thích
0
Em chào các anh chị, vui lòng giúp em vấn đề sau: Em muốn mã hóa dãy số dài từ 10 đến 16 chữ số thành chuỗi có độ dài ngắn hơn ( dưới 5 ký tự), khi cần thì em có thể giải mã chuỗi ngắn ra ngược lại số dài như ban đầu, Anh chị vui lòng giúp em ạ. Em cảm ơn.
ví dụ như này: số đầu vào: 1005002100470350 số đầu ra: cdb143 kiểu vậy

Số đầu vào có độ dài không cố định. độ dài từ 10 đến 16 chữ số,
 

File đính kèm

A./ Bạn này viết linh tinh quá:
(1) . . ." muốn mã hóa dãy số dài từ 10 đến 16 chữ số thành chuỗi có độ dài ngắn hơn ( dưới 5 ký tự)"
nhưng ví dụ thì: ví dụ như này: số đầu vào: 1005002100470350 số đầu ra: cdb143

(2) Trong file lại viết: . . . "giúp em tạo làm mã hóa số đầu vào thành số đầu ra sao cho đầu ra chỉ gồm từ 5 đến 8 ký tự bất kỳ"

B./ Chắc phải nhờ vô dãy số nguyên tố
 
Bảng chữ cái tiếng Anh có tổng cộng 26 chữ cái, cộng với 10 ký số tổng cộng là 36 ký tự. Mà 36^5=60466176 thôi. Cần tối thiểu 11 ký tự, nếu phân biệt chữ hoa/thường thì cần tối thiểu 9 ký tự.
 
Vậy ta có thể lấy thêm, ngoài 36 kí tự & số trên đã nêu như @, #, $, %, &, !, *, (, ), +, - ?, /, . . . . được không các bạn?
 
A./ Bạn này viết linh tinh quá:
(1) . . ." muốn mã hóa dãy số dài từ 10 đến 16 chữ số thành chuỗi có độ dài ngắn hơn ( dưới 5 ký tự)"
nhưng ví dụ thì: ví dụ như này: số đầu vào: 1005002100470350 số đầu ra: cdb143

(2) Trong file lại viết: . . . "giúp em tạo làm mã hóa số đầu vào thành số đầu ra sao cho đầu ra chỉ gồm từ 5 đến 8 ký tự bất kỳ"

B./ Chắc phải nhờ vô dãy số nguyên tố
Cảm ơn bạn, mình giải thích hơi lộm cộm, ý mình là làm sao để xử lý cái chuỗi số dài kia thành chuỗi ngắn hơn ( từ 5 đến 8 chữ số hoặc ký tự bất kỳ) miễn sao khi cần thì có thể giải ngược lại từ chuỗi 5-8 ký tự kia thành chuỗi dài ban đầu là được ạ
 
Vẫn hiểu ý bạn thôi, nhưng viết vậy đâm ra khỏ hiểu vì thiếu nhất quán.
& quan trọng mà mình hay gặp là trợ giúp đã 1 hồi lại bị trỡ mặt!
 
Bảng chữ cái tiếng Anh có tổng cộng 26 chữ cái, cộng với 10 ký số tổng cộng là 36 ký tự. Mà 36^5=60466176 thôi. Cần tối thiểu 11 ký tự, nếu phân biệt chữ hoa/thường thì cần tối thiểu 9 ký tự.
Vậy cũng OK ạ, vậy bạn giúp mình mã hóa ra 9 ký tự cũng được ạ, miễn sao có thể giải mã về dãy số ban đầu không có sai khác gì là được ạ
Bài đã được tự động gộp:

Vẫn hiểu ý bạn thôi, nhưng viết vậy đâm ra khỏ hiểu vì thiếu nhất quán.
& quan trọng mà mình hay gặp là trợ giúp đã 1 hồi lại bị trỡ mặt!
Hy vọng bạn hiểu ý mình và giúp mình nếu bạn biết, giúp là mình trân quý chứ trở mặt gì mình không hiếu ý ạ.
 
Lần chỉnh sửa cuối:
Bạn tách thành từng nhóm 2 chữ số, nếu thiếu thì thêm chữ số 0 bên trái cho đủ 16. Lập bảng tra các số từ 00 đến 99 (100 số) thành các ký tự tiếng Anh a-z, A-Z, 0-9 (62 ký tự) thêm 38 ký tự tiếng Việt có dấu vào là đủ 100.
 
Bạn tách thành từng nhóm 2 chữ số, nếu thiếu thì thêm chữ số 0 bên trái cho đủ 16. Lập bảng tra các số từ 00 đến 99 (100 số) thành các ký tự tiếng Anh a-z, A-Z, 0-9 (62 ký tự) thêm 38 ký tự tiếng Việt có dấu vào là đủ 100.
ý là sao ạ, anh có thể cho vào file excel được không ạ
 

File đính kèm

@
Cảm ơn bạn, mình giải thích hơi lộm cộm, ý mình là làm sao để xử lý cái chuỗi số dài kia thành chuỗi ngắn hơn ( từ 5 đến 8 chữ số hoặc ký tự bất kỳ) miễn sao khi cần thì có thể giải ngược lại từ chuỗi 5-8 ký tự kia thành chuỗi dài ban đầu là được ạ
Tìm hiểu mã Unicode , sẽ có cách ngắn, có thể 4 ký tự cũng thể hiện hết.
Nếu Excel có hàm Unichar, Unicode thì chỉ cần công thức cũng đủ mã hóa
 
@

Tìm hiểu mã Unicode , sẽ có cách ngắn, có thể 4 ký tự cũng thể hiện hết.
Nếu Excel có hàm Unichar, Unicode thì chỉ cần công thức cũng đủ mã hóa
Nếu mã hóa bằng Unicode thì mình sợ khi gõ ngược lại là có ký tự không gõ được bằng tay mà phải dùng unicode để chuyển ngược lại
 
Nếu mã hóa bằng Unicode thì mình sợ khi gõ ngược lại là có ký tự không gõ được bằng tay mà phải dùng unicode để chuyển ngược lại
Vẫn có thể gõ, thông qua mã số nhé (nhưng đúng là bất tiện)
Đã mã hóa còn lo gõ lại thì mã hóa làm chi,
Nếu muốn gõ tay thì sử dụng giải pháp khác vậy..
Nhưng Mã hóa tốt nhất là dùng Scan cho Barcode, hoặc QRcode
 
khi gõ ngược lại là có ký tự không gõ được bằng tay
Bạn cho ví dụ đi.

Nên nhớ Quy luật tiến hóa của con người: Từ thô tới tinh.
Cụ thể: Từ thô sơ tới hiện đại, từ chính xác thấp tới siêu chính xác. Muốn tạo ra máy móc có độ chính xác thì phải từ từ tuần tự nâng dần nên, chúng ta không thể một đập ăn ngay được.
Còn ký tự chữ kia, bạn nghĩ ngược lại: Làm sao con người cho nó được vào máy tính? Mọi cái cũng đều do con người vẽ bằng đôi bàn tay đấy.
 
Ngoài ra bài này bị bí nữa là khi cắt chuỗi ra mới thấy có chuỗi số 0 đứng đầu dẫn tới không đúng ví dụ đoạn giữa cắt ra là 0001 thì nó hiểu là số 1 mất, bắt tay vào làm mới thấy khó nhai
 
Hai hàm này sẽ chuyển từ hệ thập phân sang hệ khác và ngược lại tùy vào khai báo hằng sBaseStr, sBaseStr = "01" là nhị phân, sBaseStr = "0123456789ABCDEF" là thập lục phân. sBaseStr càng dài thì kết quả sẽ càng ngắn.
Mã:
Const sBaseStr As String = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
Function NumToText(ByVal sNum As Variant) As String
Dim lChars As Long, lNewNum As Variant, i As Long
lChars = Len(sBaseStr)
Do Until sNum < lChars
    lNewNum = Int(sNum / lChars)
    NumToText = Mid(sBaseStr, (sNum - lNewNum * lChars) + 1, 1) & NumToText
    sNum = lNewNum
Loop
NumToText = Mid(sBaseStr, sNum + 1, 1) & NumToText
End Function
Function TextToNum(ByVal sText As String) As Variant
Dim lChars As Long, i As Long, k As Long
lChars = Len(sBaseStr)
For i = Len(sText) To 1 Step -1
    TextToNum = TextToNum + (InStr(sBaseStr, Mid(sText, i, 1)) - 1) * lChars ^ k
    k = k + 1
Next
End Function
 
Lần chỉnh sửa cuối:
Hai hàm này sẽ chuyển từ hệ thập phân sang hệ khác và ngược lại tùy vào khai báo hằng sBaseStr, sBaseStr = "01" là nhị phân, sBaseStr = "0123456789ABCDEF" là thập lục phân. sBaseStr càng dài thì kết quả sẽ càng ngắn.
Mã:
Const sBaseStr As String = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
Function NumToText(ByVal sNum As Variant) As String
Dim lChars As Long, lNewNum As Variant, i As Long
lChars = Len(sBaseStr)
Do Until sNum < lChars
    lNewNum = Int(sNum / lChars)
    NumToText = Mid(sBaseStr, (sNum - lNewNum * lChars) + 1, 1) & NumToText
    sNum = lNewNum
Loop
NumToText = Mid(sBaseStr, sNum + 1, 1) & NumToText
End Function
Function TextToNum(ByVal sText As String) As Variant
Dim lChars As Long, i As Long, k As Long
lChars = Len(sBaseStr)
For i = Len(sText) To 1 Step -1
    TextToNum = TextToNum + (InStr(sBaseStr, Mid(sText, i, 1)) - 1) * lChars ^ k
    k = k + 1
Next
End Function
bạn ơi, cái này dùng làm sao vậy ạ, giúp mình cho vào file kèm được không. đầu vào đầu ra gõ chỗ nào ạ,
 

File đính kèm

Hàm dưới đây không tổng quát như của @huuthang_bd.
(Do yêu cầu mã có thể dài 16 ký số nên khi giải mã hàm @huuthang_bd có thể bị sai những số cuối)

1621680375297.png

PHP:
Function MaHoa(MNum As Variant) As String
Dim Rs As String, Tmp As Variant, TmpNum As Variant, Divid As Variant
TmpNum = MNum
Do
    Divid = Int(TmpNum / 62)
    Tmp = TmpNum - Divid * 62
    Select Case Tmp
        Case Is < 10
            Rs = Tmp & Rs
        Case Is < 36
            Rs = ChrW(Tmp - 9 + 64) & Rs
        Case Else
            Rs = Chr(Tmp - 35 + 96) & Rs
    End Select
    TmpNum = (TmpNum - Tmp) / 62
Loop Until TmpNum = 0
 MaHoa = Rs
End Function
    '_________________'
Function Giaima(MStr As String) As String
Dim Tmp As String, Rs As LongLong
For i = Len(MStr) To 1 Step -1
    Tmp = Mid(MStr, i, 1)
    Select Case Tmp
        Case 0 To 9
            Rs = Rs + Val(Tmp) * 62 ^ (Len(MStr) - i)
        Case "a" To "z"
            Rs = Rs + (35 + Asc(Tmp) - 96) * 62 ^ (Len(MStr) - i)
        Case "A" To "Z"
            Rs = Rs + (9 + Asc(Tmp) - 64) * 62 ^ (Len(MStr) - i)
    End Select
Next
Giaima = Rs
End Function
 
Hay quá ạ, có thể gắn file excel em kèm lên được không ạ, em không biết phải nhúng và chạy cái đoạn code trên như thế nào ạ, có phải tạo cái nút " mã hóa - giải mã" gì không hay là nó tự chạy ạ
 

File đính kèm

Hay quá ạ, có thể gắn file excel em kèm lên được không ạ, em không biết phải nhúng và chạy cái đoạn code trên như thế nào ạ, có phải tạo cái nút " mã hóa - giải mã" gì không hay là nó tự chạy ạ
Không biết sử dụng, sao biết "Hay quá" ???
 

File đính kèm

Hàm dưới đây không tổng quát như của

Function Giaima(MStr As String) As String
Dim Tmp As String, Rs As LongLong
Nhưng tôi dùng Excel 2013 32 bit thì làm gì có kiểu LongLong?

Ngày nghỉ rỗi hơi, tham gia tí
Mã:
Function encoding_number(ByVal number As Double) As String
'    mã hóa dùng 200 ký tự unicode trong Unicode Block “Latin Extended-B”, bắt đầu từ U + 0180
Dim a As Double, b As Long, result As String
    Do While number
        a = number
        number = Int(number / 200)
        b = a - number * 200
        result = ChrW(b + &H180) & result
    Loop
    encoding_number = result
End Function

Function decoding_code(ByVal code As String) As String
Dim k As Long, a As Long, result
    If Len(code) = 0 Then Exit Function
    For k = 1 To Len(code) - 2
        result = (result + (AscW(Mid(code, k, 1)) - &H180)) * 200
    Next k
    If Len(code) > 1 Then result = (result + (AscW(Mid(code, Len(code) - 1, 1)) - &H180)) * 2
    a = AscW(Mid(code, Len(code), 1)) - &H180
    result = (result + a \ 100) & (a Mod 100)
    If Mid(result, 1, 1) = "0" Then result = Mid(result, 2)
    decoding_code = result
End Function
Bài đã được tự động gộp:

Hihi, em nhìn hình file excel ra kết quả thấy thích quá ạ.
Bạn hãy nhập dữ liệu đầu vào vd. 1931825452366542 ̣(16 chữ số CÓ NGHĨA). Sauđó tính MÃ. Tiếp theo giải mã cái MÃ kia. Cuối cùng kiểm tra xem kêt quả giải mã có đúng là 1931825452366542 không nhé.
 
Lần chỉnh sửa cuối:
Nhưng tôi dùng Excel 2013 32 bit thì làm gì có kiểu LongLong?

Ngày nghỉ rỗi hơi, tham gia tí
Mã:
Function encoding_number(ByVal number As Double) As String
'    mã hóa dùng 200 ký tự unicode trong Unicode Block “Latin Extended-B”, bắt đầu từ U + 0180
Dim a As Double, b As Long, result As String
    Do While number
        a = number
        number = Int(number / 200)
        b = a - number * 200
        result = ChrW(b + &H180) & result
    Loop
    encoding_number = result
End Function

Function decoding_code(ByVal code As String) As String
Dim k As Long, a As Long, result
    If Len(code) = 0 Then Exit Function
    For k = 1 To Len(code) - 2
        result = (result + (AscW(Mid(code, k, 1)) - &H180)) * 200
    Next k
    If Len(code) > 1 Then result = (result + (AscW(Mid(code, Len(code) - 1, 1)) - &H180)) * 2
    a = AscW(Mid(code, Len(code), 1)) - &H180
    result = (result + a \ 100) & (a Mod 100)
    If Mid(result, 1, 1) = "0" Then result = Mid(result, 2)
    decoding_code = result
End Function
Bài đã được tự động gộp:


Bạn hãy nhập dữ liệu đầu vào vd. 1931825452366542 ̣(16 chữ số CÓ NGHĨA). Sauđó tính MÃ. Tiếp theo giải mã cái MÃ kia. Cuối cùng kiểm tra xem kêt quả giải mã có đúng là 1931825452366542 không nhé.
ui, mã của anh khủng quá á, em cần mã chỉ gồm ký tự a-z, A-Z và số thôi á, mã của anh như hacker ấy, hịhị
Bài đã được tự động gộp:

G1zpVtw.jpg
 

File đính kèm

  • Screenshot_6.jpg
    Screenshot_6.jpg
    69.9 KB · Đọc: 6
Code hàm decoding_code ở bài #23 "phức tạp" thế là do dữ liệu có thể có 16 chữ số. Nếu dữ liệu chỉ có nhiều nhất 15 chữ số thì
Mã:
Function decoding_code(ByVal code As String) As String
Dim k As Long, result
    If Len(code) = 0 Then Exit Function
    For k = 1 To Len(code) - 1
        result = (result + (AscW(Mid(code, k, 1)) - &H180)) * 200
    Next k
    decoding_code = result + AscW(Mid(code, Len(code), 1)) - &H180
End Function
 
Code hàm decoding_code ở bài #23 "phức tạp" thế là do dữ liệu có thể có 16 chữ số. Nếu dữ liệu chỉ có nhiều nhất 15 chữ số thì
Mã:
Function decoding_code(ByVal code As String) As String
Dim k As Long, result
    If Len(code) = 0 Then Exit Function
    For k = 1 To Len(code) - 1
        result = (result + (AscW(Mid(code, k, 1)) - &H180)) * 200
    Next k
    decoding_code = result + AscW(Mid(code, Len(code), 1)) - &H180
End Function
hic, mã của em hiện tại có 16 số anh ạ.
 
hic, mã của em hiện tại có 16 số anh ạ.
Tôi biết nên mới cung cấp code bài #23 chứ không cho code bài #25. Bài #25 chẳng qua là nói rõ lý do, vì sao tôi "xoay xở" như thế. Biết đâu có người cũng sẽ ý thức được là cần "xoay xở", nhưng họ có thể chọn cách "xoay xở" khác.
 
Tôi biết nên mới cung cấp code bài #23 chứ không cho code bài #25. Bài #25 chẳng qua là nói rõ lý do, vì sao tôi "xoay xở" như thế. Biết đâu có người cũng sẽ ý thức được là cần "xoay xở", nhưng họ có thể chọn cách "xoay xở" khác.
Em cảm ơn anh nhiều ạ
 
dạ, nhưng mã ấy copy vào web bán hàng nó ko cho ạ, help help
Tự test nhé.

Mã:
Const sBaseStr As String = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwx"

Function encoding_number(ByVal number As Double) As String
Dim a As Double, b As Long, result As String
    If number = 0 Then result = "0"
    Do While number
        a = number
        number = Int(number / 60)
        b = a - number * 60
        result = Mid(sBaseStr, b + 1, 1) & result
    Loop
    encoding_number = result
End Function

Function decoding_code(ByVal code As String) As String
Dim k As Long, a As Long, result
    If Len(code) = 0 Then Exit Function
    For k = 1 To Len(code) - 2
        result = (result + (InStr(1, sBaseStr, Mid(code, k, 1), vbBinaryCompare) - 1)) * 60
    Next k
    If Len(code) > 1 Then result = (result + (InStr(1, sBaseStr, Mid(code, Len(code) - 1, 1), vbBinaryCompare) - 1)) * 6
    a = InStr(1, sBaseStr, Mid(code, Len(code), 1), vbBinaryCompare) - 1
    result = (result + a \ 10) & (a Mod 10)
    If Mid(result, 1, 1) = "0" Then result = Mid(result, 2)
    decoding_code = result
End Function
 
Tự test nhé.

Mã:
Const sBaseStr As String = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwx"

Function encoding_number(ByVal number As Double) As String
Dim a As Double, b As Long, result As String
    If number = 0 Then result = "0"
    Do While number
        a = number
        number = Int(number / 60)
        b = a - number * 60
        result = Mid(sBaseStr, b + 1, 1) & result
    Loop
    encoding_number = result
End Function

Function decoding_code(ByVal code As String) As String
Dim k As Long, a As Long, result
    If Len(code) = 0 Then Exit Function
    For k = 1 To Len(code) - 2
        result = (result + (InStr(1, sBaseStr, Mid(code, k, 1), vbBinaryCompare) - 1)) * 60
    Next k
    If Len(code) > 1 Then result = (result + (InStr(1, sBaseStr, Mid(code, Len(code) - 1, 1), vbBinaryCompare) - 1)) * 6
    a = InStr(1, sBaseStr, Mid(code, Len(code), 1), vbBinaryCompare) - 1
    result = (result + a \ 10) & (a Mod 10)
    If Mid(result, 1, 1) = "0" Then result = Mid(result, 2)
    decoding_code = result
End Function
Tuyệt vời quá anh ạ, Cảm ơn anh nhiều nhiều.

kMXgSiU.jpg
 
Tôi cũng thử test và có cảm giác với các số lớn gần bằng 10^16 thì có chút sai số (kể cả LongLong).
He he. Tức những "số" có 16 chữ số không tin tưởng được. Nhưng anh để ý là không phải số nào cũng thế. Trên hình đính kèm thì chỉ những số lẻ mới sai. Tuy nhiên tôi nghi là với những số 16 chữ số thì sẽ có những số sai, không nhất thiết số lẻ sai. Có thể vài số liên tiếp đều bị sai.

Thôi thì "xoay xở" tiếp. Không chỉ với decoding mà cả encoding cũng phải "xoay xở".

Alô alô, chủ thớt test lại code mới nhé.

Nếu chuỗi nguồn rỗng thì kết quả cũng rỗng.
Mã:
Const sBaseStr As String = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwx"

Function encoding_number(ByVal number As String) As String
Dim a As Double, b As Long, so As Double, result As String
    If Len(number) = 1 Then
        encoding_number = Mid(sBaseStr, number + 1, 1)
        number = ""
    End If
    If Len(number) = 0 Then Exit Function
    b = Right(number, 1)
    a = Left(number, Len(number) - 1)
    so = Int(a / 6 + b / 60)
    b = (a - so * 6) * 10 + b
    result = Mid(sBaseStr, b + 1, 1)
    Do While so
        a = so
        so = Int(so / 60)
        b = a - so * 60
        result = Mid(sBaseStr, b + 1, 1) & result
    Loop
    encoding_number = result
End Function

Function decoding_code(ByVal code As String) As String
Dim k As Long, a As Long, result
    If Len(code) = 0 Then Exit Function
    For k = 1 To Len(code) - 2
        result = (result + (InStr(1, sBaseStr, Mid(code, k, 1), vbBinaryCompare) - 1)) * 60
    Next k
    If Len(code) > 1 Then result = (result + (InStr(1, sBaseStr, Mid(code, Len(code) - 1, 1), vbBinaryCompare) - 1)) * 6
    a = InStr(1, sBaseStr, Mid(code, Len(code), 1), vbBinaryCompare) - 1
    result = (result + a \ 10) & (a Mod 10)
    If Mid(result, 1, 1) = "0" Then result = Mid(result, 2)
    decoding_code = result
End Function
 
He he. Tức những "số" có 16 chữ số không tin tưởng được. Nhưng anh để ý là không phải số nào cũng thế. Trên hình đính kèm thì chỉ những số lẻ mới sai. Tuy nhiên tôi nghi là với những số 16 chữ số thì sẽ có những số sai, không nhất thiết số lẻ sai. Có thể vài số liên tiếp đều bị sai.

Thôi thì "xoay xở" tiếp. Không chỉ với decoding mà cả encoding cũng phải "xoay xở".

Alô alô, chủ thớt test lại code mới nhé.

Nếu chuỗi nguồn rỗng thì kết quả cũng rỗng.
Mã:
Const sBaseStr As String = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwx"

Function encoding_number(ByVal number As String) As String
Dim a As Double, b As Long, so As Double, result As String
    If Len(number) = 1 Then
        encoding_number = Mid(sBaseStr, number + 1, 1)
        number = ""
    End If
    If Len(number) = 0 Then Exit Function
    b = Right(number, 1)
    a = Left(number, Len(number) - 1)
    so = Int(a / 6 + b / 60)
    b = (a - so * 6) * 10 + b
    result = Mid(sBaseStr, b + 1, 1)
    Do While so
        a = so
        so = Int(so / 60)
        b = a - so * 60
        result = Mid(sBaseStr, b + 1, 1) & result
    Loop
    encoding_number = result
End Function

Function decoding_code(ByVal code As String) As String
Dim k As Long, a As Long, result
    If Len(code) = 0 Then Exit Function
    For k = 1 To Len(code) - 2
        result = (result + (InStr(1, sBaseStr, Mid(code, k, 1), vbBinaryCompare) - 1)) * 60
    Next k
    If Len(code) > 1 Then result = (result + (InStr(1, sBaseStr, Mid(code, Len(code) - 1, 1), vbBinaryCompare) - 1)) * 6
    a = InStr(1, sBaseStr, Mid(code, Len(code), 1), vbBinaryCompare) - 1
    result = (result + a \ 10) & (a Mod 10)
    If Mid(result, 1, 1) = "0" Then result = Mid(result, 2)
    decoding_code = result
End Function
Em cảm ơn các anh đã nhiệt tình code cho em ạ, thật không biết nói gì hơn, các anh thật là siêu quá ạ.
 
Mình có cách mã hóa (ĐỐI XỨNG) như dữ liệu sau:

ABCDE0
FGHIJ1
KLMNO2
PQRST3
UVWXY4
Z56789
KHONG CO GI QUY HON DOC LAP TU DO
TRUONG
SA0123
BCDEF4
HIJKL5
MPQVW6
XYZ
7​
89
B0FEA UF A1 IMW 0FE OFU CTH LM OF

Chúc mọi người vui!
 
LM4vBDB.jpg
Em test nó ra thế này ạ, em có sửa tên funtion thành mahoa và giaima để khỏi trùng với tên cũ ạ
Tôi đã nói rồi mà không nghe thì chịu.
Ít ra thì cột A và cột giải mã phải định dạng là TEXT trước khi nhập dữ liệu.
 
Thôi thì "xoay xở" tiếp. Không chỉ với decoding mà cả encoding cũng phải "xoay xở".
Sau khi anh "xoay sở" thì vừa đủ cho chuỗi 16 số hay sao ấy anh ạ. Trên 16 ký số lại sai.
Tôi cũng đang xoay sở nhưng vẫn sai, mà sai chỗ khác. (chỗ sai tìm ra nguyên nhân ở 2 dòng cuối trong hình, chắc phải xoay sở tiếp )

1621876361820.png
 
Sau khi anh "xoay sở" thì vừa đủ cho chuỗi 16 số hay sao ấy anh ạ. Trên 16 ký số lại sai.
Tôi chỉ làm cho tới 16 chữ số mà anh. Tôi không làm cho 17 hoặc nhiều hơn chữ số.

Trích

Bài #1
Em muốn mã hóa dãy số dài từ 10 đến 16 chữ số thành chuỗi có độ dài ngắn hơn
...
Số đầu vào có độ dài không cố định. độ dài từ 10 đến 16 chữ số,

Bài #26
hic, mã của em hiện tại có 16 số anh ạ.

Nếu là số chữ số bất kỳ thì không thể dùng code ấy được.
 
Góp vui cách mã hóa chuỗi số <=30 ký tự
Mã:
Function MaHoa(ByVal iNum As String) As String
  Dim j&, n&, tmp$, tmp2$, inter$, inter2$, imod, Res$
  If iNum = Empty Or Len(iNum) > 30 Then Exit Function
  If iNum = "0" Then Res = "0"
  n = Len(sBaseStr)
  Do While iNum
    If Len(iNum) > 15 Then
      j = Int(Len(iNum) / 2)
      tmp = Mid(iNum, 1, j)
      inter = Int(tmp / n)
      imod = tmp - inter * n
      
      tmp2 = imod & Mid(iNum, j + 1, j + 1)
      inter2 = Int(tmp2 / n)
      imod = tmp2 - inter2 * n
      iNum = inter & inter2
    Else
      inter = Int(iNum / n)
      imod = iNum - inter * n
      iNum = inter
    End If
    Res = Mid(sBaseStr, imod + 1, 1) & Res
  Loop
  MaHoa = Res
End Function
 
Lần mò thử hàm mà không biết có sai không
Mã:
B2=UNICHAR(MID($A2;1;4)+10000)&IFERROR(UNICHAR(MID($A2;5;4)+10000);"")&IFERROR(UNICHAR(MID($A2;9;4)+10000);"")&IFERROR(UNICHAR(MID($A2;13;4)+10000);"")
C2=(--MID((UNICODE(MID(B2;1;1)));2;4)&IFERROR(MID((UNICODE(MID(B2;2;1)));2;4);"")&IFERROR(MID((UNICODE(MID(B2;3;1)));2;4);"")&IFERROR(MID((UNICODE(MID(B2;4;1)));2;4);""))
1621935807536.png
 

File đính kèm

Lần mò thử hàm mà không biết có sai không
Mã:
B2=UNICHAR(MID($A2;1;4)+10000)&IFERROR(UNICHAR(MID($A2;5;4)+10000);"")&IFERROR(UNICHAR(MID($A2;9;4)+10000);"")&IFERROR(UNICHAR(MID($A2;13;4)+10000);"")
C2=(--MID((UNICODE(MID(B2;1;1)));2;4)&IFERROR(MID((UNICODE(MID(B2;2;1)));2;4);"")&IFERROR(MID((UNICODE(MID(B2;3;1)));2;4);"")&IFERROR(MID((UNICODE(MID(B2;4;1)));2;4);""))
View attachment 259395
ui, mã hóa ký tự hoa cả mắt, không đọc và gõ vào lại được luôn, chỉ có copy. :D
Bài đã được tự động gộp:

Nếu cần mã hóa ký tự thì inbox mình nhé.

View attachment 259328
Dạ thôi ạh, em sợ kiểu mã hóa này lắm ạ
Bài đã được tự động gộp:

Tôi đã nói rồi mà không nghe thì chịu.
Ít ra thì cột A và cột giải mã phải định dạng là TEXT trước khi nhập dữ liệu.
Để em làm lại ạ
 
Có lỗi đây anh

View attachment 259388

Cách chia đôi dãy số tôi cũng đã nghĩ đến, sẽ khó khăn khi giải mã trở về chuỗi số gốc
Viết thêm hàm chia chuỗi để tính phần nguyên và số dư của phép chia
Dùng function MaHoaSo chung cho mã hóa hoặc giải mã, hoặc dùng riêng như trong file
Do hàm giải mã tính phép nhân trên số nên giới hạn số chữ số là 27
Xem ví dụ cách dùng các hàm trong file
Mã:
Option Explicit
Const sBaseStr As String = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwx"

Function MaHoaSo(ByVal iNum As String, Optional bMaHoa As Boolean = True) As String
  If bMaHoa = True Then
    MaHoaSo = MaHoa(iNum)
  Else
    MaHoaSo = GiaiMa(iNum)
  End If
End Function

Function GiaiMa(ByVal iCode As String) As String
  Dim k&, j&, j2&, tmp$, tmp2$, Res$
 
  If Len(iCode) = 0 Then Exit Function
  Res = InStr(1, sBaseStr, Mid(iCode, 1, 1), vbBinaryCompare) - 1
  If Len(iCode) = 1 Then
    GiaiMa = Res
  Else
    For k = 2 To Len(iCode)
      If Len(Res) < 13 Then
        Res = CDbl(Res) * 60 + InStr(1, sBaseStr, Mid(iCode, k, 1), vbBinaryCompare) - 1
      Else
        j = Int(Len(Res) / 2): j2 = Len(Res) - j
        tmp2 = CDbl(Right(Res, j2)) * 60 + InStr(1, sBaseStr, Mid(iCode, k, 1), vbBinaryCompare) - 1
        tmp = CDbl(Left(Res, j)) * 60
        If Len(tmp2) > j2 Then
          tmp = CDbl(tmp) + CDbl(Left(tmp2, Len(tmp2) - j2))
        End If
        Res = tmp & Right(tmp2, j2)
      End If
    Next k
    GiaiMa = Res
  End If
End Function

Function MaHoa(ByVal iNum As String) As String
  Dim j&, N&, tmp$, tmp2$, inter$, inter2$, imod$, Res$
  If iNum = Empty Or Len(iNum) > 27 Then Exit Function
  If iNum = "0" Then Res = "0"
  N = Len(sBaseStr)
  Do While iNum
    If Len(iNum) > 15 Then
      Call ChiaChuoi(imod, iNum, 60)
    Else
      inter = Int(iNum / N)
      imod = iNum - inter * N
      iNum = inter
    End If
    Res = Mid(sBaseStr, imod + 1, 1) & Res
  Loop
  MaHoa = Res
End Function

Private Sub ChiaChuoi(imod As String, iNum As String, ByVal div As Long)
  Dim N&, i&, Res$
  N = Len(iNum)
  imod = Empty
  For i = 1 To N
    imod = imod & Mid(iNum, i, 1)
    If CLng(imod) >= div Then
      Res = Res & Int(imod / div)
      imod = imod - Int(imod / div) * div
    Else
      If Res <> Empty Then Res = Res & "0"
    End If
  Next i
  iNum = Res
End Sub
 

File đính kèm

ui, mã hóa ký tự hoa cả mắt, không đọc và gõ vào lại được luôn, chỉ có copy. :D
Ui ẩu quá làm xong quên không test lại trường hợp khi cắt không đủ 4 ký tự, sửa lại chút
Mã:
B2=UNICHAR(MID($A2;1;4)+10^IF(LEN($A2)>4*1;4;LEN($A2)))&IFERROR(UNICHAR(MID($A2;5;4)+10^IF(LEN($A2)>4*2;4;LEN($A2)-4*1));"")&IFERROR(UNICHAR(MID($A2;9;4)+10^IF(LEN($A2)>4*3;4;LEN($A2)-4*2));"")&IFERROR(UNICHAR(MID($A2;13;4)+10^(LEN($A2)-4*3));"")
C2=(MID((UNICODE(MID(B2;1;1)));2;4)&IFERROR(MID((UNICODE(MID(B2;2;1)));2;4);"")&IFERROR(MID((UNICODE(MID(B2;3;1)));2;4);"")&IFERROR(MID((UNICODE(MID(B2;4;1)));2;4);""))
 

File đính kèm

Bài này nếu mọi người Cộng Trừ Nhân Chia theo kiểu số thì sẽ bị giới hạn theo kiểu số. Mình viết lại hàm tính toán theo kiểu chuỗi thì sẽ không bị giới hạn nữa.
PHP:
Option Explicit

Const sBaseStr As String = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwx"

Function Encode(ByVal iNum As String, Optional iBase As String = sBaseStr) As String
  If iNum = 0 Then Encode = Mid(iBase, 1, 1): Exit Function
  Dim x&, y&, z$, nBase&
  nBase = Len(iBase)
  While iNum > 0
    x = 1
    While CLng(Left(iNum, x)) < nBase And x < Len(iNum)
      x = x + 1
    Wend
    y = CLng(Left(iNum, x))
    For x = x To Len(iNum)
      z = z & y \ nBase
      y = CLng((y Mod nBase) & Mid(iNum, x + 1, 1))
    Next x
    iNum = z: z = ""
    Encode = Mid(iBase, y + 1, 1) & Encode
  Wend
End Function

Function Decode(ByVal iCode As String, Optional iBase As String = sBaseStr) As String
  Dim x&, nBase$, tmp$
  nBase = Len(iBase) & ""
  Decode = "" & InStr(1, iBase, Right(iCode, 1)) - 1
  tmp = "1"
  For x = Len(iCode) - 1 To 1 Step -1
    tmp = Mul(nBase, tmp)
    Decode = Add(Mul(tmp, "" & InStr(1, iBase, Mid(iCode, x, 1)) - 1), Decode)
  Next x
End Function

Private Function Add(ByVal iNum1 As String, ByVal iNum2 As String) As String
  Dim x&, tmp As Byte
  iNum1 = StrReverse(iNum1)
  iNum2 = StrReverse(iNum2)
  x = IIf(Len(iNum1) > Len(iNum2), Len(iNum1), Len(iNum2))
  For x = 1 To x
    tmp = tmp + Val(Mid(iNum1, x, 1)) + Val(Mid(iNum2, x, 1))
    Add = tmp Mod 10 & Add
    tmp = tmp \ 10
  Next x
  If tmp > 0 Then Add = tmp & Add
End Function

Private Function Mul(ByVal iNum1 As String, ByVal iNum2 As String) As String
  Dim x&, tmp$
  iNum2 = StrReverse(iNum2)
  Mul = Mul_X(iNum1, Mid(iNum2, 1, 1))
  For x = 2 To Len(iNum2)
    tmp = tmp & 0
    Mul = Add(Mul_X(iNum1, Mid(iNum2, x, 1)) & tmp, Mul)
  Next x
End Function

Private Function Mul_X(ByVal iNum As String, iMul As String) As String
  Dim x&, tmp As Byte
  iNum = StrReverse(iNum)
  For x = 1 To Len(iNum)
    tmp = tmp + Val(Mid(iNum, x, 1)) * Val(iMul)
    Mul_X = tmp Mod 10 & Mul_X
    tmp = tmp \ 10
  Next x
  If tmp > 0 Then Mul_X = tmp & Mul_X
End Function
 
Nếu tôi không lầm thì code ở bài #51 cho kết quả sai với chuỗi nguồn là "1005001800538130" (16 chữ số). Kết quả mã là 5x0eZDa8o.

Giải mã 5x0eZDa8o thì được "100500180538130" (15 chữ số)

1005001800538130 (16 chữ số) <> 100500180538130 (15 chữ số)
--------------
Tôi cũng vừa mới viết xong code dùng để cộng trừ, nhân và chia số lớn. Và sử dụng code đó để mã hóa.

Tuy nhiên khi vào GPE thì gặp code của Ngô Hải Đăng ở bài 53. Code rất thú vị tuy mới chỉ nhìn qua.

Code của tôi có cả phép trừ và phép chia (trả về phần nguyên và phần dư khi chia. Vd. 27 chia 4 thì phần nguyên = 6, phần dư = 3). Số bị chia la số lớn, số chia là số nhỏ.

Code hiện thời của tôi chỉ phục vụ số có tới 200 chữ số. Có thể sửa nhẹ nhàng để phục vụ 1000 chữ số và hơn nữa. Giới hạn chỉ ở bộ nhớ cho phép dùng bởi cấu trúc so_rat_lon.
Trong tập tin số ở A7 và C7 có 100 chữ số. Mã ở B7 có 56 ký tự.

mahoa.jpg

Mã:
Private Const sBaseStr As String = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwx"
Private Const base = 100

Private Type LargeArray
    mang(1 To 100) As Byte
End Type

Private Type so_rat_lon
    length As Integer
    data As LargeArray
End Type

Sub InitNum(ByVal text As String, v As so_rat_lon)
Dim length As Long, k As Long, result As so_rat_lon
    If Len(text) Mod 2 = 1 Then text = "0" & text
    length = Len(text) \ 2
    result.length = length
    For k = 1 To length
        result.data.mang(k) = Mid(text, 2 * (length - k) + 1, 2)
    Next k
    v = result
End Sub

Function NumToStr(v As so_rat_lon) As String
Dim k As Long, s As String
    If v.length = 0 Then Exit Function
    s = Format(v.data.mang(v.length), "0")
    For k = v.length - 1 To 1 Step -1
        s = s & Format(v.data.mang(k), "00")
    Next k
    NumToStr = s
End Function

Sub vmul(a As so_rat_lon, ByVal n As Byte, v As so_rat_lon)   ' v = a*n. Tra ve v
Dim length As Long, k As Long, p As Integer, nho As Byte
    length = a.length
    v.length = length
    For k = 1 To length
        p = a.data.mang(k) * CLng(n) + nho
        v.data.mang(k) = p Mod base
        nho = p \ base
    Next k
    If nho Then
        v.length = length + 1
        v.data.mang(length + 1) = nho
    End If
End Sub

Sub vadd(a As so_rat_lon, b As so_rat_lon, v As so_rat_lon)   ' v = a + b. Tra ve v
Dim length As Integer, k As Integer, nho As Byte
    v = a
    length = a.length
    If length < b.length Then length = b.length
    For k = 1 To length
        nho = nho + v.data.mang(k) + b.data.mang(k)
        v.data.mang(k) = nho Mod base
        nho = nho \ base
    Next k
    If nho > 0 Then
        v.data.mang(length + 1) = nho
        v.length = length + 1
    Else
        v.length = length
    End If
End Sub

Sub vdiv(a As so_rat_lon, ByVal b As Byte, nguyen As so_rat_lon, du As Byte)  ' a = b*nguyen + du. Tra ve nguyen, du
Dim k As Integer, so As Long, rest As Byte, v As so_rat_lon, u As so_rat_lon
    nguyen.length = a.length
    For k = a.length To 1 Step -1
        so = rest * 100 + a.data.mang(k)
        nguyen.data.mang(k) = so \ b
        rest = so Mod b
    Next k
    du = rest
    k = nguyen.length
    Do While nguyen.data.mang(k) = 0
        k = k - 1
        If k = 0 Then Exit Do
    Loop
    nguyen.length = k
End Sub

Sub vsub(a As so_rat_lon, b As so_rat_lon, v As so_rat_lon)   ' v = a - b. Tra ve v
Dim length As Integer, k As Integer, vay As Byte
    If (b.length = 0) Or a.length < b.length Then Err.Raise number:=9999, Description:="Tham so khong hop le"
    For k = 1 To a.length
        If a.data.mang(k) - vay < b.data.mang(k) Then
            If k = a.length Then Err.Raise number:=9999, Description:="Tham so khong hop le"
            v.data.mang(k) = a.data.mang(k) - vay + 100 - b.data.mang(k)
            vay = 1
        Else
            v.data.mang(k) = a.data.mang(k) - vay - b.data.mang(k)
            vay = 0
        End If
    Next k
    k = a.length
    Do While v.data.mang(k) = 0
        k = k - 1
        If k = 0 Then Exit Do
    Loop
    v.length = k
End Sub

Function encoding_number(ByVal number As String) As String
Dim a As so_rat_lon, nguyen As so_rat_lon, du As Byte, result As String, text As String
    InitNum number, a
    Do While a.length > 0
        vdiv a, 60, nguyen, du
        result = Mid(sBaseStr, du + 1, 1) & result
        a = nguyen
        text = NumToStr(nguyen)
    Loop
    encoding_number = result
End Function

Function decoding_code(ByVal code As String) As String
Dim k As Long, text As String, a As so_rat_lon, b As so_rat_lon, result As so_rat_lon
    If Len(code) = 0 Then Exit Function
    For k = 1 To Len(code) - 1
        text = InStr(1, sBaseStr, Mid(code, k, 1), vbBinaryCompare) - 1
        InitNum text, b
        a = result
        vadd a, b, result
        a = result
        vmul a, 60, result
    Next k
    text = InStr(1, sBaseStr, Mid(code, Len(code), 1), vbBinaryCompare) - 1
    InitNum text, b
    a = result
    vadd a, b, result
    decoding_code = NumToStr(result)
End Function
 

File đính kèm

Nếu tôi không lầm thì code ở bài #51 cho kết quả sai với chuỗi nguồn là "1005001800538130" (16 chữ số). Kết quả mã là 5x0eZDa8o.

Giải mã 5x0eZDa8o thì được "100500180538130" (15 chữ số)

1005001800538130 (16 chữ số) <> 100500180538130 (15 chữ số)
--------------
Tôi cũng vừa mới viết xong code dùng để cộng trừ, nhân và chia số lớn. Và sử dụng code đó để mã hóa.

Tuy nhiên khi vào GPE thì gặp code của Ngô Hải Đăng ở bài 53. Code rất thú vị tuy mới chỉ nhìn qua.

Code của tôi có cả phép trừ và phép chia (trả về phần nguyên và phần dư khi chia. Vd. 27 chia 4 thì phần nguyên = 6, phần dư = 3). Số bị chia la số lớn, số chia là số nhỏ.

Code hiện thời của tôi chỉ phục vụ số có tới 200 chữ số. Có thể sửa nhẹ nhàng để phục vụ 1000 chữ số và hơn nữa. Giới hạn chỉ ở bộ nhớ cho phép dùng bởi cấu trúc so_rat_lon.
Trong tập tin số ở A7 và C7 có 100 chữ số. Mã ở B7 có 56 ký tự.

View attachment 259453

Mã:
Private Const sBaseStr As String = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwx"
Private Const base = 100

Private Type LargeArray
    mang(1 To 100) As Byte
End Type

Private Type so_rat_lon
    length As Integer
    data As LargeArray
End Type

Sub InitNum(ByVal text As String, v As so_rat_lon)
Dim length As Long, k As Long, result As so_rat_lon
    If Len(text) Mod 2 = 1 Then text = "0" & text
    length = Len(text) \ 2
    result.length = length
    For k = 1 To length
        result.data.mang(k) = Mid(text, 2 * (length - k) + 1, 2)
    Next k
    v = result
End Sub

Function NumToStr(v As so_rat_lon) As String
Dim k As Long, s As String
    If v.length = 0 Then Exit Function
    s = Format(v.data.mang(v.length), "0")
    For k = v.length - 1 To 1 Step -1
        s = s & Format(v.data.mang(k), "00")
    Next k
    NumToStr = s
End Function

Sub vmul(a As so_rat_lon, ByVal n As Byte, v As so_rat_lon)   ' v = a*n. Tra ve v
Dim length As Long, k As Long, p As Integer, nho As Byte
    length = a.length
    v.length = length
    For k = 1 To length
        p = a.data.mang(k) * CLng(n) + nho
        v.data.mang(k) = p Mod base
        nho = p \ base
    Next k
    If nho Then
        v.length = length + 1
        v.data.mang(length + 1) = nho
    End If
End Sub

Sub vadd(a As so_rat_lon, b As so_rat_lon, v As so_rat_lon)   ' v = a + b. Tra ve v
Dim length As Integer, k As Integer, nho As Byte
    v = a
    length = a.length
    If length < b.length Then length = b.length
    For k = 1 To length
        nho = nho + v.data.mang(k) + b.data.mang(k)
        v.data.mang(k) = nho Mod base
        nho = nho \ base
    Next k
    If nho > 0 Then
        v.data.mang(length + 1) = nho
        v.length = length + 1
    Else
        v.length = length
    End If
End Sub

Sub vdiv(a As so_rat_lon, ByVal b As Byte, nguyen As so_rat_lon, du As Byte)  ' a = b*nguyen + du. Tra ve nguyen, du
Dim k As Integer, so As Long, rest As Byte, v As so_rat_lon, u As so_rat_lon
    nguyen.length = a.length
    For k = a.length To 1 Step -1
        so = rest * 100 + a.data.mang(k)
        nguyen.data.mang(k) = so \ b
        rest = so Mod b
    Next k
    du = rest
    k = nguyen.length
    Do While nguyen.data.mang(k) = 0
        k = k - 1
        If k = 0 Then Exit Do
    Loop
    nguyen.length = k
End Sub

Sub vsub(a As so_rat_lon, b As so_rat_lon, v As so_rat_lon)   ' v = a - b. Tra ve v
Dim length As Integer, k As Integer, vay As Byte
    If (b.length = 0) Or a.length < b.length Then Err.Raise number:=9999, Description:="Tham so khong hop le"
    For k = 1 To a.length
        If a.data.mang(k) - vay < b.data.mang(k) Then
            If k = a.length Then Err.Raise number:=9999, Description:="Tham so khong hop le"
            v.data.mang(k) = a.data.mang(k) - vay + 100 - b.data.mang(k)
            vay = 1
        Else
            v.data.mang(k) = a.data.mang(k) - vay - b.data.mang(k)
            vay = 0
        End If
    Next k
    k = a.length
    Do While v.data.mang(k) = 0
        k = k - 1
        If k = 0 Then Exit Do
    Loop
    v.length = k
End Sub

Function encoding_number(ByVal number As String) As String
Dim a As so_rat_lon, nguyen As so_rat_lon, du As Byte, result As String, text As String
    InitNum number, a
    Do While a.length > 0
        vdiv a, 60, nguyen, du
        result = Mid(sBaseStr, du + 1, 1) & result
        a = nguyen
        text = NumToStr(nguyen)
    Loop
    encoding_number = result
End Function

Function decoding_code(ByVal code As String) As String
Dim k As Long, text As String, a As so_rat_lon, b As so_rat_lon, result As so_rat_lon
    If Len(code) = 0 Then Exit Function
    For k = 1 To Len(code) - 1
        text = InStr(1, sBaseStr, Mid(code, k, 1), vbBinaryCompare) - 1
        InitNum text, b
        a = result
        vadd a, b, result
        a = result
        vmul a, 60, result
    Next k
    text = InStr(1, sBaseStr, Mid(code, Len(code), 1), vbBinaryCompare) - 1
    InitNum text, b
    a = result
    vadd a, b, result
    decoding_code = NumToStr(result)
End Function
Tuyệt vời quá, bạn có thể xử lý thêm giúp tôi chuỗi cần mã hóa là 1 đoạn văn bản như "Việt Nam" được không? Ngoài ra khi mã hóa bằng một chuỗi có số 0 đầu tiên khi giải mã không còn số 0 ở đầu nữa, bạn xử lý thêm đoạn này giúp tôi với.
 
Tuyệt vời quá, bạn có thể xử lý thêm giúp tôi chuỗi cần mã hóa là 1 đoạn văn bản như "Việt Nam" được không?
Tôi không mã văn bản đâu. Tôi không có nhu cầu gì cả. Excel và VBA cũng chỉ là thích chơi chứ công việc không bao giờ dùng. Vì là đam mê thì cái gì thích, lúc nào có hứng mới làm.
Ngoài ra khi mã hóa bằng một chuỗi có số 0 đầu tiên khi giải mã không còn số 0 ở đầu nữa, bạn xử lý thêm đoạn này giúp tôi với.
Bạn thay
Mã:
Function NumToStr(v As so_rat_lon) As String
Dim k As Long, s As String
    If v.length = 0 Then Exit Function
    s = Format(v.data.mang(v.length), "0")
    For k = v.length - 1 To 1 Step -1
        s = s & Format(v.data.mang(k), "00")
    Next k
    NumToStr = s
End Function

bằng

Mã:
Function NumToStr(v As so_rat_lon) As String
Dim k As Long, s As String
    If v.length = 0 Then Exit Function
    For k = v.length To 1 Step -1
        s = s & Format(v.data.mang(k), "00")
    Next k
    NumToStr = s
End Function
 
Lần chỉnh sửa cuối:
Các anh thật là siêu. em chỉ biết đứng nhìn chứ ko biết gì món này, Xin phép anh batman1 cho em dùng file trong post #54 của anh. Em xin cảm ơn, Các anh thảo luận tiếp đi ạ
 
Tôi không mã văn bản đâu. Tôi không có nhu cầu gì cả. Excel và VBA cũng chỉ là thích chơi chứ công việc không bao giờ dùng. Vì là đam mê thì cái gì thích, lúc nào có hứng mới làm.

Bạn thay
Mã:
Function NumToStr(v As so_rat_lon) As String
Dim k As Long, s As String
    If v.length = 0 Then Exit Function
    s = Format(v.data.mang(v.length), "0")
    For k = v.length - 1 To 1 Step -1
        s = s & Format(v.data.mang(k), "00")
    Next k
    NumToStr = s
End Function

bằng

Mã:
Function NumToStr(v As so_rat_lon) As String
Dim k As Long, s As String
    If v.length = 0 Then Exit Function
    For k = v.length To 1 Step -1
        s = s & Format(v.data.mang(k), "00")
    Next k
    NumToStr = s
End Function
Buồn quá, bạn lại không có nhu cầu.
Bài đã được tự động gộp:

Tôi không mã văn bản đâu. Tôi không có nhu cầu gì cả. Excel và VBA cũng chỉ là thích chơi chứ công việc không bao giờ dùng. Vì là đam mê thì cái gì thích, lúc nào có hứng mới làm.

Bạn thay
Mã:
Function NumToStr(v As so_rat_lon) As String
Dim k As Long, s As String
    If v.length = 0 Then Exit Function
    s = Format(v.data.mang(v.length), "0")
    For k = v.length - 1 To 1 Step -1
        s = s & Format(v.data.mang(k), "00")
    Next k
    NumToStr = s
End Function

bằng

Mã:
Function NumToStr(v As so_rat_lon) As String
Dim k As Long, s As String
    If v.length = 0 Then Exit Function
    For k = v.length To 1 Step -1
        s = s & Format(v.data.mang(k), "00")
    Next k
    NumToStr = s
End Function
Bạn ơi cột A nhập "012" sau đó bấm nút, cột B = C, cột C= 12 (mong muốn kết quả trả về cột C như cột A)
 
Bạn ơi cột A nhập "012" sau đó bấm nút, cột B = C, cột C= 12 (mong muốn kết quả trả về cột C như cột A)
Vì là số nên số 0 đứng đầu không có ý nghĩa nên có 2 cách giải quyết. Cách một là viết code không xử lý số 0 đứng đầu ở 2 phần mã hóa và giải mã (Ví dụ 012 --> 0C --> 012). Cách hai là trước khi mã hóa thêm số 1 (hoặc số nào khác 0) vào đầu chuỗi mã hóa, rồi khi giải mã thì lấy từ vị trí thứ 2.
 
Vì là số nên số 0 đứng đầu không có ý nghĩa nên có 2 cách giải quyết. Cách một là viết code không xử lý số 0 đứng đầu ở 2 phần mã hóa và giải mã (Ví dụ 012 --> 0C --> 012). Cách hai là trước khi mã hóa thêm số 1 (hoặc số nào khác 0) vào đầu chuỗi mã hóa, rồi khi giải mã thì lấy từ vị trí thứ 2.
Tôi thấy cách 2 là đúng với kiểu mã hóa nếu có thể bạn xử lý giúp và thêm mã hóa cả chuỗi văn bản như "Việt Nam ơi cố lên" giúp tôi với
 
Tôi thấy cách 2 là đúng với kiểu mã hóa nếu có thể bạn xử lý giúp và thêm mã hóa cả chuỗi văn bản như "Việt Nam ơi cố lên" giúp tôi với
Bạn mở chủ đề mới thì đúng hơn, chủ đề này là mã hoá dãy số dài thành mã ngắn, không phải mã hoá văn bản.
 
Các phép tính chuyển mã theo dạng chuỗi không bị giới hạn số ký tự số, xử lý trực tiếp không thông qua các hàm trung gian tốc độ nhanh hơn tí, thêm tùy chọn các ký tự mã hóa
Xem ví dụ cách dùng Function trong file
Mã:
Option Explicit
Const sBaseStr As String = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwx"

Function MaHoaSo(ByVal iStr As String, Optional bMaHoa As Boolean = True, Optional iBase As String = sBaseStr) As String
'Function MaHoaSo: Chuyen So iStr thanh Ma hoac chuyen Ma iStr thanh So
'bMaHoa: Mac dinh = True chuyen So thanh Ma, bMaHoa = False chuyen Ma thanh So
'iBase: Chuoi cac ky tu Ma Hoa, Mac dinh = sBaseStr
  If bMaHoa = True Then
    MaHoaSo = MaHoa(iStr, iBase)
  Else
    MaHoaSo = GiaiMa(iStr, iBase)
  End If
End Function

Function MaHoa(ByVal iNum As String, Optional iBase As String = sBaseStr) As String
  Dim j&, div&, tmp$, imod$, Res$
'Function MaHoa: Chuyen So iNum thanh Ma
'iBase: Chuoi cac ky tu Ma Hoa, Mac dinh = sBaseStr
  div = Len(iBase)
  Do While iNum <> Empty
    tmp = Empty:    imod = Empty
    For j = 1 To Len(iNum)
      imod = imod & Mid(iNum, j, 1)
      If CLng(imod) >= div Then
        tmp = tmp & Int(imod / div)
        imod = imod - Int(imod / div) * div
      Else
        If tmp <> Empty Then tmp = tmp & "0"
      End If
    Next j
    iNum = tmp
    Res = Mid(iBase, imod + 1, 1) & Res
  Loop
  MaHoa = Res
End Function

Function GiaiMa(ByVal iCode As String, Optional iBase As String = sBaseStr) As String
  Dim mul&, k&, j&, inter&, t&, tmp$, Res$
'Function GiaiMa: Chuyen Ma iCode thanh So
'iBase: Chuoi cac ky tu Ma Hoa, Mac dinh = sBaseStr
  If Len(iCode) = 0 Then Exit Function
  mul = Len(iBase)
  Res = InStr(1, iBase, Mid(iCode, 1, 1), vbBinaryCompare) - 1
  For k = 2 To Len(iCode)
    inter = Empty: tmp = Empty
    For j = Len(Res) To 1 Step -1
      t = Mid(Res, j, 1) * mul + inter
      If j = Len(Res) Then t = t + InStr(1, iBase, Mid(iCode, k, 1), vbBinaryCompare) - 1
      inter = Int(t / 10)
      tmp = (t Mod 10) & tmp
    Next j
    Res = inter & tmp
  Next k
  GiaiMa = Res
End Function
 

File đính kèm

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

Back
Top Bottom