INPUT: "I love visual basic 6"
OUTPUT: "LGOUGKGMOIJRI9FJI9FJRFJFPROVFJGUUGU"
Note that my entrance is of varying length, but my exit is of fixed size.
This is what I need, no matter the length of the data entry, but I need it to have a fixed length output.
Unless there are feasible limits on the size of your original string, and the "exit size" of the fixed length "result" is large enough, then what you are asking is impossible.*
If you want any size to turn in to a fixed size, then a moment of consideration should lead you to the conclusion that going the other direction (a fixed size to any size) is impossible.
*Imagine that you say the original string can be up to 10000 characters. Then, you could set the fixed result size to 10000 characters, pad any input with spaces to make it equal to 10000 characters, and do a 1-for-1 character replacement using a method of your choice. Of course, that probably isn't what you are looking for, but just pointing out that with those limitations it is possible.
*Imagine that you say the original string can be up to 10000 characters. Then, you could set the fixed result size to 10000 characters, pad any input with spaces to make it equal to 10000 characters, and do a 1-for-1 character replacement using a method of your choice. Of course, that probably isn't what you are looking for, but just pointing out that with those limitations it is possible.
An idea where it looks like it can be implemented.
An idea where it looks like it can be implemented.
In the case instead of 10,000 I need 255.
I think the partial answer to your question is: compress then encrypt.
The only way you can get a fixed length of 255 or any value really is to be able to compress the string first to a size of your value or less. Then encrypt the compressed string. The other option was already mentioned, set a max size for your encrypted string and never encrypt a string that is larger than that value.
Insomnia is just a byproduct of, "It can't be done"
Already discussed earlier: encrypt using simple substitution, Xor, or another custom encryption. If result is less than 255, then pad the string with random/dummy data before encryption. However, you'll need a way to encode into your string, the original length of the string so you know where the dummy data starts/ends.
Read articles on Xor encryption and substitution encryption. Those are fairly easy to code yourself.
Another option is to use RLE8 algorithm used for bitmaps. That algo compresses 1 byte values (strings consist of bytes). That algo has a high probability of reducing the size of the string first, but is not guaranteed to reduce the size of the data. However, you may not want to compress+encrypt.
Edited: instead of encoding length of original string, when padding is needed, a simpler solution: append a vbNullChar (or two of them if unicode) after the shorter text, then pad with dummy data up to 255 or whatever value you want. After decryption, simply find the vbNullChar. If it doesn't exist, then no padding was used and if it does exist then the real data is left of that null char.
Last edited by LaVolpe; Sep 2nd, 2020 at 01:54 PM.
Insomnia is just a byproduct of, "It can't be done"
First, I agree with everything that's been said so far. Also, even if you do view hashing as a form of encryption, it's only weak ... so just to get that out of the way as well.
Now, using a hash code, you could view it as "sort of" encryption if you were willing to do the following:
1. You have some message.
2. You hash it and get a hash code.
3. You give the hash code to someone else.
4. That person hashes some message that they "think" you sent them.
5. They compare their hashed message to the one you sent them.
6. If they match, it's probably (but not absolutely) the same message.
Notice that the hash code was never used in any reverse-hash algorithm to "recover" the original message (because you can't do that).
Hope That Helps,
Elroy
EDIT: And, to do true encryption, the encrypted message will ALWAYS be at least as long as the original message. And, just to be clear on this as well, you can compress before encryption to attempt to shorten it. And, the original message from compression can (at least in most cases, depending on the compression method) be recovered from the original message.
In fact, if you want, you could also view compression as a form of weak encryption, and that's really what you're sort of talking about.
Last edited by Elroy; Sep 2nd, 2020 at 01:33 PM.
Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.
Just FYI: simple substitution or XOR encryption is meant to keep honest people honest. Those encryption algos won't stop someone that really wants to hack your encryption.
However, simply adding spaces to the end of a short string to fill up the 255 length buffer is even weaker. Anyone looking at a few of your encrypted strings might see a pattern where the last 'n' characters seem to be the same in all strings. Hmmm, maybe now one can determine the length of the encrypted string. Suggestion: fill them with random characters instead of just one character be it a space or anything else. See post #12
Insomnia is just a byproduct of, "It can't be done"
This AES implementation encodes the output w/ base64 so output is bigger than input but becomes printable (can be sent in email for instance). The vbNullChar appending seems cheap and reasonable padding scheme for text input.
Here's a bit of fun using XOR encryption with a password phrase. It limits the output to 255 characters.
The code was whipped up quick, just copy & paste to a new form & run
Code:
Option Explicit
Dim sResult As String ' encrypted text
Dim WithEvents cmdHide As CommandButton
Dim WithEvents cmdShow As CommandButton
Private Function pvEncryptXor(Data As String, Phrase As String) As String
' pass raw string in to get encrypted one out
' pass encrypted string in to get raw one out; Phrase must be same each time
Dim aKey() As Byte, aData() As Byte
Dim sString As String, lMax As Long
Dim k As Long, c As Long
aKey() = StrConv(Phrase, vbFromUnicode)
aData() = StrConv(Data, vbFromUnicode)
lMax = Len(Phrase) - 1
For c = 0 To Len(Data) - 1
aData(c) = aData(c) Xor aKey(k) Xor (c And &HFF)
If k = lMax Then k = 0 Else k = k + 1
Next
pvEncryptXor = StrConv(aData(), vbUnicode)
' can get creative with the above routine; for example:
' you can start in the middle of the phrase
' you can start at the end and decrement k instead of incrementing
End Function
Private Sub cmdHide_Click()
Dim sText As String
sText = Left$(Me.Controls("txtData").Text & vbNullChar & Space$(255), 255)
sResult = pvEncryptXor(sText, Me.Controls("txtPhrase").Text)
Me.Controls("txtResult").Text = sResult
End Sub
Private Sub cmdShow_Click()
Dim sText As String
sText = pvEncryptXor(sResult, Me.Controls("txtPhrase").Text)
If InStr(sText, vbNullChar) <> 0 Then
sText = Left$(sText, InStr(sText, vbNullChar) - 1)
End If
Me.Controls("txtResult").Text = sText
End Sub
Private Sub Form_Load()
Dim Y As Single
With Me.Controls.Add("VB.TextBox", "txtPhrase")
.Visible = True: .Enabled = True
.Text = "Encryption Phrase"
.Width = .Width * 3
Y = Y + .Height
End With
With Me.Controls.Add("VB.TextBox", "txtData")
.Visible = True: .Enabled = True
.Text = "Data to Encrypt"
.MaxLength = 255
.Top = Y: .Width = .Width * 3
Y = Y + .Height
End With
With Me.Controls.Add("VB.TextBox", "txtResult")
.Visible = True: .Enabled = True
.Text = "Result"
.Top = Y: .Width = .Width * 3
Y = Y + .Height
End With
Set cmdHide = Me.Controls.Add("VB.CommandButton", "cmdEncrypt")
With cmdHide
.Visible = True: .Enabled = True
.Caption = "Encrypt"
.Top = Y: .Width = .Width * 2
Y = Y + .Height
End With
Set cmdShow = Me.Controls.Add("VB.CommandButton", "cmdDecipher")
With cmdShow
.Visible = True: .Enabled = True
.Caption = "Decipher"
.Top = Y: .Width = .Width * 2
Y = Y + .Height
End With
End Sub
using a textbox to display the encryption isn't ideal since the text may have non-printable characters or text truncated. This is why the result is cached to a form-level variable so we can ensure we are deciphering the exact string that was encrypted vs a potentially truncated string from a textbox.
edited: can be played with to convert for unicode text usage and/or larger output strings (255 as is now)
edited again: cleaned up the main routine and fixed logic: didn't get through entire phrase before starting over; off by one.
Last edited by LaVolpe; Sep 3rd, 2020 at 05:31 PM.
Insomnia is just a byproduct of, "It can't be done"
Here's another attempt, using a laughable cipher with a few silly complications (I think that's the watchmaker's term for it) added.
In order to ensure printable text it limits input to characters " " through "}" zapping all others to question marks and using "~" as the delimiter for short inputs.
One might fiddle a bit to accommodate additional printables from the ANSI extensions to ASCII, though that risks the usual portability concerns. Unicode is more of a challenge, as are control characters. If we remove the "printable text" restriction things get easier of course.
I have no idea why so many restrictions were imposed, I just assumed they are and that I have them correct. Did I use the word "silly" yet?
Code:
Option Explicit
Private Function Decrypt(ByVal Cipher As String) As String
Dim Bytes() As Byte
Dim Deciphered() As Byte
Dim I As Long
Dim ISwap As Long
Dim L As Long
Bytes = StrConv(Cipher, vbFromUnicode)
ReDim Deciphered(254)
For I = 0 To 253
ISwap = (I \ 2) * 2 + ((I + 1) Mod 2)
Deciphered(ISwap) = (Bytes(I) - 32 - ISwap * 3 Mod 95 + 95) Mod 95 + 32
Next
Deciphered(I) = (Bytes(I) - 32 - I * 3 Mod 95 + 95) Mod 95 + 32
Decrypt = StrConv(Deciphered, vbUnicode)
L = InStr(Decrypt, "~")
If L > 0 Then Decrypt = Left$(Decrypt, L - 1)
Decrypt = StrReverse(Decrypt)
End Function
Private Function Encrypt(ByVal Plain As String) As String
'Only the printable ASCII range (less the "~") is acceptable.
Dim Bytes() As Byte
Dim L As Long
Dim I As Long
Dim Ciphered() As Byte
Dim ISwap As Long
Bytes = StrConv(StrReverse(Plain), vbFromUnicode)
L = UBound(Bytes)
'Zap unsupported characters to "?":
For I = 0 To L
If Bytes(I) < 32 Or Bytes(I) > 125 Then Bytes(I) = 63
Next
If L < 254 Then
'Delimit plain text and pad it:
ReDim Preserve Bytes(254)
Bytes(L + 1) = 126 'The "~"
For I = L + 2 To 254
Bytes(I) = &H60 + I Mod 16
Next
End If
'Now "Rot(I * 3)" encipher and swap pairs of bytes, then encipher the odd byte at 254:
ReDim Ciphered(254)
For I = 0 To 253
ISwap = (I \ 2) * 2 + ((I + 1) Mod 2)
Ciphered(ISwap) = (Bytes(I) - 32 + I * 3 Mod 95) Mod 95 + 32
Next
Ciphered(I) = (Bytes(I) - 32 + I * 3 Mod 95) Mod 95 + 32
Encrypt = StrConv(Ciphered, vbUnicode)
End Function
Private Sub cmdDecrypt_Click()
Text3.Text = Decrypt(Text2.Text)
End Sub
Private Sub cmdEncrypt_Click()
Text2.Text = Encrypt(Text1.Text)
End Sub
Private Sub Form_Load()
If Right$(Text1.Text, 2) = vbNewLine Then
Text1.Text = Left$(Text1.Text, Len(Text1.Text) - 2)
End If
End Sub