我正在尝试制作一个CLI应用来保护/取消保护文本文档, 我所做的是简单的2次Base64编码/解码。
当我尝试将包含特殊字符的文档编码为“ñ”“ç”或“áéíóúàèìòùäëïöü,文档采用ANSI编码,然后当我解码之前编码的base64字符串时,我得到一个”? “字符而不是原始的”ñ“字符或其他拉丁字符。
我使用默认的ANSI编码来获取字节字符并写入文本文件,我不明白为什么我遇到麻烦因为如果我尝试编码/解码msgbox中的“ñ”字符只是为了测试然后解码的base64字符串被打印为“ñ”字符好,可能问题是在“List(Of String)”对象中可能存储坏的解码字符串?
我如何解决这个问题并使其更适用于角色类型?
这是VS2012中针对FW 4.0编写的完整源代码:
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
答案 0 :(得分:0)
我不确定您测试此代码的确切条件,但它应该可以正常工作。您所引用的错误很可能是通过在读/写时选择了错误的编码方法而引起的。在任何情况下,使用默认配置和使用您的代码我都没有发现任何问题:
Result.Add(Encrypt_String("ñ")) 'Result(0) = "OFE9PQ=="
System.IO.File.WriteAllText("file path", Result(0))
Dim out As String = Decrypt_String(System.IO.File.ReadAllText("file path").Trim()) 'out = "ñ"
请告诉您遇到此问题的具体条件。
<强>更新强>
当用ReadAllText
替换第一行时(从只写“ñ”的文件中),我什么都没得到(空字符串)。我必须将编码设置为Default
以使其按上述方式工作:
Result.Add(Encrypt_String(System.IO.File.ReadAllText("file path", System.Text.Encoding.Default).Trim()))
默认编码(System.Text.Encoding.Default.EncodingName
)的名称为Western European (Windows)
。
因此,在读取文件时选择正确的编码是一个问题,而不是使用.NET变量。奇怪的是, ReadAllText
默认情况下不会考虑Encoding.Default
(!)。