Типичная реализация strlen
:
size_t strlen(char *s)
{
size_t len = 0;
while(*s++) len++;
return len;
}
Другими словами, он определяет длину строки, увеличивая указатель на начало строки, пока не будет достигнут нулевой терминатор. Поскольку ваш буфер является просто блоком символа 'h'
без нулевого терминатора, вызов strlen
для него имеет неопределенное поведение.
Ваш второй пример кода, где вы явно добавляете нулевой терминатор после вызова malloc
, а затем используете strcat
для многократной записи в строку, не имеет этой проблемы, поскольку строковые литералы автоматически заканчиваются нулем. [119 ]
Кроме того, не приводят к результату malloc , если только вам не нужен ваш код для совместимости с C ++.
Вот способ сделать это в VB От: http://www.devcity.net/Articles/47/1/encrypt_querystring.aspx
Обертка для кода шифрования: Передайте свои querystring параметры в это и измените ключ!!!
Private _key as string = "!#$a54?3"
Public Function encryptQueryString(ByVal strQueryString As String) As String
Dim oES As New ExtractAndSerialize.Encryption64()
Return oES.Encrypt(strQueryString, _key)
End Function
Public Function decryptQueryString(ByVal strQueryString As String) As String
Dim oES As New ExtractAndSerialize.Encryption64()
Return oES.Decrypt(strQueryString, _key)
End Function
Код шифрования:
Imports System
Imports System.IO
Imports System.Xml
Imports System.Text
Imports System.Security.Cryptography
Public Class Encryption64
Private key() As Byte = {}
Private IV() As Byte = {&H12, &H34, &H56, &H78, &H90, &HAB, &HCD, &HEF}
Public Function Decrypt(ByVal stringToDecrypt As String, _
ByVal sEncryptionKey As String) As String
Dim inputByteArray(stringToDecrypt.Length) As Byte
Try
key = System.Text.Encoding.UTF8.GetBytes(Left(sEncryptionKey, 8))
Dim des As New DESCryptoServiceProvider()
inputByteArray = Convert.FromBase64String(stringToDecrypt)
Dim ms As New MemoryStream()
Dim cs As New CryptoStream(ms, des.CreateDecryptor(key, IV), _
CryptoStreamMode.Write)
cs.Write(inputByteArray, 0, inputByteArray.Length)
cs.FlushFinalBlock()
Dim encoding As System.Text.Encoding = System.Text.Encoding.UTF8
Return encoding.GetString(ms.ToArray())
Catch e As Exception
Return e.Message
End Try
End Function
Public Function Encrypt(ByVal stringToEncrypt As String, _
ByVal SEncryptionKey As String) As String
Try
key = System.Text.Encoding.UTF8.GetBytes(Left(SEncryptionKey, 8))
Dim des As New DESCryptoServiceProvider()
Dim inputByteArray() As Byte = Encoding.UTF8.GetBytes( _
stringToEncrypt)
Dim ms As New MemoryStream()
Dim cs As New CryptoStream(ms, des.CreateEncryptor(key, IV), _
CryptoStreamMode.Write)
cs.Write(inputByteArray, 0, inputByteArray.Length)
cs.FlushFinalBlock()
Return Convert.ToBase64String(ms.ToArray())
Catch e As Exception
Return e.Message
End Try
End Function
End Class
Я первоначально собирался согласиться с Joseph Bui на том основании, что это будет больше процессора, эффективного для использования метода POST вместо этого, веб-стандарты диктуют, что, если запрос не изменяет данные по серверу, ПОЛУЧИТЬ метод должен использоваться.
Это будет намного больше кода для шифрования данных, чем просто использовать POST.
Я не могу дать Вам готовое решение первое, что пришло на ум, но необходимо избежать TripleDES, так как это не столь безопасно как другие методы шифрования.
Если бы я делал его, то я просто взял бы весь URL (домен и querystring) как объект URI, зашифровал бы его с одной из встроенных библиотек.NET и предоставил бы его как crypt
объект. Когда я должен дешифровать его, действительно так, затем создайте новый объект URI, который позволит Вам вернуть все из исходного querystring.
Почему Вы пытаетесь зашифровать свою строку запроса? Если данные уязвимы, необходимо использовать SSL. Если Вы волнуетесь по поводу кого-то смотрящего через плечо пользователя, используйте, формируются, POST вместо ДОБИРАЮТСЯ.
Я думаю, что довольно вероятно, что существует лучшее решение для Вашей фундаментальной проблемы, чем шифрование строки запроса.
Вот своего рода необычная версия дешифровать функции от примера Brian, выше которого Вы могли использовать, если бы Вы только собирались использовать это для QueryString, поскольку это возвращает NameValueCollection вместо строки. Это также содержит небольшое исправление, поскольку пример Brian повредится без
stringToDecrypt = stringToDecrypt.Replace(" ", "+")
если существуют какие-либо символы 'пространства' в строке для дешифрования:
Public Shared Function DecryptQueryString(ByVal stringToDecrypt As String, ByVal encryptionKey As String) As Collections.Specialized.NameValueCollection
Dim inputByteArray(stringToDecrypt.Length) As Byte
Try
Dim key() As Byte = System.Text.Encoding.UTF8.GetBytes(encryptionKey.Substring(0, encryptionKey.Length))
Dim IV() As Byte = {&H12, &H34, &H56, &H78, &H90, &HAB, &HCD, &HEF}
Dim des As New DESCryptoServiceProvider()
stringToDecrypt = stringToDecrypt.Replace(" ", "+")
inputByteArray = Convert.FromBase64String(stringToDecrypt)
Dim ms As New MemoryStream()
Dim cs As New CryptoStream(ms, des.CreateDecryptor(key, IV), CryptoStreamMode.Write)
cs.Write(inputByteArray, 0, inputByteArray.Length)
cs.FlushFinalBlock()
Dim encoding As System.Text.Encoding = System.Text.Encoding.UTF8
Dim decryptedString As String = encoding.GetString(ms.ToArray())
Dim nameVals() As String = decryptedString.Split(CChar("&"))
Dim queryString As New Collections.Specialized.NameValueCollection(nameVals.Length)
For Each nameValPair As String In nameVals
Dim pair() As String = nameValPair.Split(CChar("="))
queryString.Add(pair(0), pair(1))
Next
Return queryString
Catch e As Exception
Throw New Exception(e.Message)
End Try
End Function
Я надеюсь, что Вы находите это полезным!