我正在尝试制作一个 CLI 应用程序来保护/取消保护文本文档,我所做的是简单的 2 次 Base64 编码/解码。
当我尝试将包含特殊字符的文档编码为“ñ”“ç”或“áéíóú àèìòù äëïöü 时,问题就开始了,这些文档采用 ANSI 编码,然后当我解码之前编码的 base64 字符串时,我得到一个“?”字符原始的“ñ”字符或其他拉丁字符。
我使用默认的 ANSI 编码来获取字节字符并写入文本文件,我不明白为什么会遇到问题,因为如果我尝试在 msgbox 中对“ñ”字符进行编码/解码只是为了进行测试,那么解码的base64字符串打印为“ñ”字符好,也许问题出在“List(Of String)”对象中,该对象可能存储坏的解码字符串?
我如何解决这个问题并使其对角色类型更通用?
这是针对 FW 4.0 用 VS2012 编写的完整源代码:
Module Main
#Region " Variables "
' Stores the file information
Dim INFO As IO.FileInfo
' Stores the TextFile Content
Private Content As String()
' Stores the Result Text
Private Result As New List(Of String)
' Error messages
Private ErrorMessages As New Dictionary(Of Integer, String) From { _
{1, "Insuficient arguments"}, _
{2, "Too many arguments"}, _
{3, "File does not exist"}, _
{4, "Unrecognized parametter. Valid parametters are: /P, /Protect, /U, /Unprotect"}}
Dim Logo As String = <a><![CDATA[
D""""""'DDD CC'""""'cCC dP
D dddd. `D C' .ccc. `C 88
D DDDDD D .d8888b. C CCCCCccC 88d888b. dP dP 88d888b. d8888P
D DDDDD D 88' `88 C CCCCCccC 88' `88 88 88 88' `88 88
D dddd' .D 88. .88 C. `ccc' .C 88 88. .88 88. .88 88
D .DD `88888P' CC. .dC dP `8888P88 88Y888P' dP
DDDDDDDDDDD CCCCCCCCCCC .88 88
d8888P dP
By Elektro H@cker
]]></a>.Value
Dim Syntax As String = <a><![CDATA[
[+] Syntax:
DoCrypt.exe [Switch] [TextFile]
[+] Switches:
/P (or) /Protect | Protect text file.
/U (or) /Unprotect | Unprotect text file.
[+] Usage examples:
# Protect file:
DoCrypt.exe /P "Document.txt"
# Unprotect file:
DoCrypt.exe /U "Protected Document.txt"
]]></a>.Value
#End Region
Sub Main()
' My.Computer.Clipboard.SetText(Encrypt_String("ñ"))
' MsgBox(Decrypt_String("OFE9PQ=="))
Console.WriteLine(Logo)
Parse_Arguments()
Environment.Exit(0)
End Sub
' Pase commandline arguments
Private Sub Parse_Arguments()
Select Case My.Application.CommandLineArgs.Count
Case 0
Help()
Case Is < 2 ' Insuficcient arguments
PrintError(1)
Case Is > 2 ' Too many arguments
PrintError(2)
Case 2
If Not IO.File.Exists(My.Application.CommandLineArgs.Item(1)) Then
PrintError(3)
Else
INFO = New IO.FileInfo(My.Application.CommandLineArgs.Item(1))
End If
Try
Content = IO.File.ReadAllLines(INFO.FullName)
Catch ex As Exception
Console.WriteLine(ex.Message)
End Try
End Select
Select Case My.Application.CommandLineArgs.Item(0).ToLower
Case "/p", "/protect"
For Each line As String In Content
Result.Add(Encrypt_String(line))
Console.WriteLine(Result.Last)
Next
If Not String.IsNullOrEmpty(INFO.Extension) Then
IO.File.WriteAllLines(String.Format("{0} Encrypted{1}", _
INFO.FullName.Substring(0, INFO.FullName.LastIndexOf(".")), INFO.Extension), _
Result, System.Text.Encoding.Default)
Else
IO.File.WriteAllLines(INFO.FullName & " Encrypted.txt", Result, System.Text.Encoding.Default)
End If
Case "/u", "/unprotect"
For Each line As String In Content
Result.Add(Decrypt_String(line))
Console.WriteLine(Result.Last)
Next
If Not String.IsNullOrEmpty(INFO.Extension) Then
IO.File.WriteAllLines(String.Format("{0} Decrypted{1}", _
INFO.FullName.Substring(0, INFO.FullName.LastIndexOf(".")), INFO.Extension), _
Result, System.Text.Encoding.Default)
Else
IO.File.WriteAllLines(INFO.FullName & " Decrypted.txt", Result, System.Text.Encoding.Default)
End If
Case Else
PrintError(4)
End Select
Environment.Exit(0)
End Sub
' Prints Help syntax
Private Sub Help()
Console.WriteLine(Syntax)
Environment.Exit(1)
End Sub
' Prints An ErrorMessage
Private Sub PrintError(ByVal Errormessage As Short)
Console.WriteLine("[X] Error: " & ErrorMessages(Errormessage))
Environment.Exit(1)
End Sub
' Encrypt String
Public Function Encrypt_String(ByVal str As String) As String
Return Convert.ToBase64String(System.Text.Encoding.Default.GetBytes( _
Convert.ToBase64String(System.Text.Encoding.Default.GetBytes(str))))
End Function
' Decrypt String
Private Function Decrypt_String(ByVal str As String) As String
Return System.Text.Encoding.Default.GetString(Convert.FromBase64String( _
System.Text.Encoding.Default.GetString(Convert.FromBase64String(str))))
End Function
End Module