How can I write a Vigenère encryption in Qbasic without the use of arrays?
I understand the math to encrypt a message:
Ca = Ma + Kb (mod 26)
And to decrypt a message:
Ma = Ca – Kb (mod 26).
I'm struggling with the syntax as I haven't found much information online.
You can solve this easily without using any arrays.
Below is my all-(Q)BASIC solution.
The MID$ function extracts one character from a string, and the ASC function converts the character into its ASCII code. Subtracting 65 produces a number in the range [0,25]. The encrypted number is turned back into a character using the CHR$ function. Hereafter the MID$ statement is used to put the encrypted character back in the string.
Because of the different lengths between the message and the encryption key, a separate iteration variable (j%) is needed to repeatedly walk through the key string.
msg$ = "ENCRYPTION"
PRINT msg$
key$ = "CLINTON"
k% = LEN(key$)
j% = 1
FOR i% = 1 TO LEN(msg$)
a% = (ASC(MID$(msg$, i%, 1)) - 65) + (ASC(MID$(key$, j%, 1)) -65)
MID$(msg$, i%) = CHR$(65 + a% + 26 * (a% > 25))
j% = j% + 1 + k% * (j% = k%)
NEXT i%
PRINT msg$
The above snippet could do without one - 65 and one + 65, but I've left these in for clarity.
The decryption process is quite similar. 3 little changes are all that it takes:
j% = 1
FOR i% = 1 TO LEN(msg$)
a% = (ASC(MID$(msg$, i%, 1)) - 65) - (ASC(MID$(key$, j%, 1)) -65)
MID$(msg$, i%) = CHR$(65 + a% - 26 * (a% < 0))
j% = j% + 1 + k% * (j% = k%)
NEXT i%
PRINT msg$
Running both snippets in a row produces:
ENCRYPTION
GYKERDGKZV
ENCRYPTION
What about a version of the code that can deal with spaces, punctuation marks, and accented characters?
The code is very similar and even a bit simpler:
msg$ = "This is any text that needs encrypting. So sayeth Sep Roland!"
PRINT msg$
key$ = "Blaise de Vigenère"
k% = LEN(key$)
j% = 1
FOR i% = 1 TO LEN(msg$)
a% = ASC(MID$(msg$, i%, 1)) + ASC(MID$(key$, j%, 1))
MID$(msg$, i%) = CHR$(a% + 256 * (a% > 255))
j% = j% + 1 + k% * (j% = k%)
NEXT i%
PRINT msg$
j% = 1
FOR i% = 1 TO LEN(msg$)
a% = ASC(MID$(msg$, i%, 1)) - ASC(MID$(key$, j%, 1))
MID$(msg$, i%) = CHR$(a% - 256 * (a% < 0))
j% = j% + 1 + k% * (j% = k%)
NEXT i%
PRINT msg$
I will not reproduce any output here because that would be a real pita...
Are these strange embedded conditions correct?
(a% + 26 * (a% > 25))
Consider the equivalent simple code:
IF a% > 25 THEN
a% = a% - 26
ENDIF
If the a% variable is greater than 25, we need to subtract 26.
Nonetheless the (a% + 26 * (a% > 25)) form uses addition.
This so happens because a TRUE condition evaluates to -1.
If a% > 25 is TRUE we get (a% + 26 * -1) -> a% - 26
If a% > 25 is FALSE we get (a% + 26 * 0) -> a%
You can simply get the ASCII value of the char as a number and then subtract the character value of A. You would get a number in the range [0, 26). Then you'd perform encryption / decryption as you've stated. To get back a valid character value then reverse and add the value of A. This works because the letters of the English alphabet (the ABC) are listed in order in ASCII.
To get the ciphertext or plaintext simply iterate over all the characters in the string (possibly after checking that it doesn't contain any other characters) and append the encrypted / decrypted character to a new string, and finally return that. Viola, no arrays, just strings, characters and numerical values.
That's all folks.
Related
I am trying to find a way to mimic the curve or a product release schedule.
This is the release schedule for the number of units for a product. We have a new product coming out that will have the same release schedule in a curve. that should look like this:
I want it to have the same curve but stretched over a longer period of time:
I tried to just break it down by the phase but the results didn't match the same curve:
I have access to excel, VBA, and R. Is there a way that I can get a calculation that would allow me to match the curve structure if I have a different length of time and possibly a different total amount of units? I know I'm supposed to show what I have tried as well but nothing has gotten me even close.
You can get your NewData with Interpolation:
'Year .... 0 - 25
'x .... =year/25*17
'Units .... =Linterp($A$2:$B$19; x) --- A2:B19 is your input
Function Linterp(ByRef Tbl As Range, ByRef dX As Double) As Variant
' copied from
' https://www.ozgrid.com/forum/index.php?thread/82496-interpolate-an-array-of-numbers/
'
' shg 06 Jun 1997
' Linear interpolator / extrapolator
' Tbl is a two-column range containing known x, known y, sorted ascending
Dim i As Long ' index to Tbl
Dim nRow As Long ' rows in Tbl
Dim dXAbv As Double ' Tbl value above dX
Dim dXBlo As Double ' Tbl values below dX
Dim dRF As Double ' row fraction
nRow = Tbl.Rows.Count
If nRow < 2 Or Tbl.Columns.Count <> 2 Then
Linterp = "Table must have >= 2 rows, exactly two columns"
Exit Function '-------------------------------------------------------->
End If
If dX < Tbl(1, 1).Value Then ' dX < xmin, extrapolate first two entries
i = 1
Else
i = WorksheetFunction.Match(dX, WorksheetFunction.Index(Tbl, 0, 1), 1)
If dX = Tbl(i, 1).Value Then ' dX is exact from table
Linterp = Tbl(i, 2)
Exit Function '---------------------------------------------------->
ElseIf i = nRow Then ' dX > xmax, extrapolate last two entries
i = nRow - 1
'Else
' dX lies between two rows, so interpolate entries i, i+1
' which is what happens by default
End If
End If
dXAbv = Tbl(i, 1).Value
dXBlo = Tbl(i + 1, 1).Value
dRF = (dX - dXAbv) / (dXBlo - dXAbv) ' row fraction
Linterp = Tbl(i, 2).Value * (1 - dRF) + Tbl(i + 1, 2).Value * dRF
End Function
Your input data is in A2:B19!
The new data is columns D, E and F!
D1: Year
D2: 0
D3: 1
...
E1: x
E2: =D2/25*17
E3: =D3/25*17
...
F1: Units
F2: =Linterp($A$2:$B$19;E2)
F3: =Linterp($A$2:$B$19;E3)
...
I am trying to reproduce the multiplication over GF(256) of this question. Specifically, I am trying d4*02 in sage. According to the authors, this multiplication is 𝟷𝟶𝟷𝟷𝟶𝟶𝟷𝟷. In Sage I tried
k.<a> = FiniteField(256, impl='givaro', repr='int')
print(k((a**2+a**4+a**6+a**7)*(a))) # a**2+a**4+a**6+a**7 is d4 and a is 2
181
But 181 is not equal to 𝟷𝟶𝟷𝟷𝟶𝟶𝟷𝟷. What I am doing wrong? Could you help me, please?
You need to give your finite field constructor the correct modulus for Rijndael.
# Rijndael finite field
k.<a> = GF(2^8, modulus=x^8+x^4+x^3+x+1)
r = (a^7 + a^6 + a^4 + a^2) * a
v = r.integer_representation()
print(r, v, hex(v))
Output
a^7 + a^5 + a^4 + a + 1 179 0xb3
It's usually more convenient to specify field elements using integers. Eg,
# Rijndael finite field
k.<a> = GF(2^8, modulus=x^8+x^4+x^3+x+1)
kint = k._cache.fetch_int
p, q = [kint(u) for u in (0xd4, 0x02)]
r = p * q
v = r.integer_representation()
print(r, v, hex(v))
Alternatively, you can use a list and a dict to convert integers to and from field elements. The following code does the second multiplication from the linked question.
# Rijndael finite field
k.<a> = GF(2^8, modulus=x^8+x^4+x^3+x+1)
i2f = sorted(k)
f2i = {v: i for i, v in enumerate(i2f)}
p, q = [i2f[u] for u in (0xbf, 0x03)]
print(p)
print(q)
r = p * q
v = f2i[r]
print(r, v, hex(v))
Output
a^7 + a^5 + a^4 + a^3 + a^2 + a + 1
a + 1
a^7 + a^6 + a^4 + a^3 + a 218 0xda
I'd like to decode this string:
X-OVH-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrfeelgedrvdduucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuqfggjfenuceurghilhhouhhtmecufedttdenucgohfhorhgsihguuggvnhfjughrucdlhedttddm
How can I do this?
There is a Tor hidden service you can use to decode the tag located at http://6jbnmws2zq2m2fsfmpwnssgsrxovohgggphymkd4df2pgcw7ccrdy6ad.onion
According to it, the X-OVH-SPAMCAUSE you gave translates to this:
Vade Retro 01.394.21 AS+AV+AP+RT Profile: OVH; Bailout: 300; ^ForbiddenHdr (500)
Starting from lkraider's great Python answer, I improved the accuracy. It turns out that the offset characters (c..g) are alternately appended and prepended. So instead of just checking if one of them is in the pair, it is necessary to differentiate between, e.g., fh and hf, by keeping track of even or odd pairs.
def decode(msg):
text = ""
for i in range(0, len(msg), 2):
# add position as extra parameter
text += unrot(msg[i: i + 2], i // 2)
return text
def unrot(pair, pos, key=ord('x')):
# "even" position => 2nd char is offset
if pos % 2 == 0:
# swap letters in pair
pair = pair[1] + pair[0]
# treat 1st char as offset
offset = (ord('g') - ord(pair[0])) * 16
# map to original character
return chr(sum(ord(c) for c in pair) - key - offset)
print(decode('gggruggvucftvghtrhho'))
https://gist.github.com/DoubleYouEl/e3de97293ce3d5452b3be7a336a06ad7
Looks to be some obfuscation by rotating chars. I made an attempt at it using Python. It's not perfect but mostly seems to work:
def decode(msg):
text = []
for i in range(0, len(msg), 2):
text.append(unrot(msg[i: i + 2]))
return str.join('', text)
def unrot(pair, key=ord('x')):
offset = 0
for c in 'cdefgh':
if c in pair:
offset = (ord('g') - ord(c)) * 16
break
return chr(sum(ord(c) for c in pair) - key - offset)
print(decode('gggruggvucftvghtrhho'))
https://gist.github.com/lkraider/9530798a695586fc1580d0728966f6f0
I improved the given Python solutions by Ikraider and DoubleYou and added a JavaScript solution, too.
Python:
def Decode(msg):
return ''.join([chr(ord(msg[i * 2]) + ord(msg[i * 2 + 1]) - 1768 + ord(msg[i * 2 + 1 - (i & 1)]) * 16) for i in range(len(msg) // 2)])
print(Decode('gggruggvucftvghtrhho'))
JavaScript:
function Decode(msg)
{
return Array(msg.length >> 1).fill(0).map((_, i) => String.fromCharCode(msg[i * 2].charCodeAt(0) + msg[i * 2 + 1].charCodeAt(0) - 1768 + (msg[i * 2 + 1 - (i & 1)].charCodeAt(0) << 4))).join('');
}
console.log(Decode('gggruggvucftvghtrhho'));
If
I = (V+13) % 26
Then what is V in terms of 'I'. Basically how can you take the Mod operator on the other side of equation ?
I = (V+13) %26
This means V+13 = k*26 + I, and k=Z, I=[0,1,...,26-1]. (1)
so
V = k*26 + I -13
now, because I is remainder from division by 26, I=[0,1,...,26-1].
This means:
I%26=I, I divided by 26 is just I.
so:
I = (V+13) %26
I%26 = (V+13) %26
this is not the same as I%26 = (V+13)
because I%26 = (V+13) implies V+13 = [0,1,...,26-1] what contradicts (1), (V+13 might be greater than 26-1).
Corollary:
V = (I%26) - 13 is not correct
V = (I%26) - 13 + k*26, k=Z is correct
For example, when NOT working with integer division the following is true
x/4 + x/2 = x*(1/4+1/2) = x * 3/4
When dealing with integer division is there a way to reduce x/4 + x/2 into this form:
x * (int1/int2)? If so, how?
The question reduce x/4 + x/2 into this form: x * (int1/int2) appears to be not quite the query you want. Forcing the (int1/int2) division first simple results in int3.
So let's work with
reduce x/4 + x/2 into this form: (x * int1)/int2
As others have mentioned, there are issues with this that hints to its impossibility. So I'll propose yet another form that might work for you in that it is still one access to x and no branching.
reduce x/4 + x/2 into this form: ((x/int1)*int2)/int3
x/4 + x/2 reduces to ((x/2)*3)/2. It takes advantage that 4 is a multiple of 2.
Note: There remains a possibility of overflow for large |x| beginning with INTMAX/3*2 or so.
Test code
int test2(int x) {
int y1 = x/4 + x/2;
int y2 = ((x/2)*3)/2;
printf("%3d %3d %3d %d\n", x, y1, y2, y1==y2);
return y1==y2;
}
I don't think you'll be able to do this. Take for example
5 \ 3 + 5 \ 2 = 1 + 2 = 3
where \ denotes integer division.
Now look at the same expression with regular division
a / b + a / c = a(b + c) / bc
If we were to try to apply this rule to the example above, substituting \ for /, we would get this:
5 \ 3 + 5 \ 2 = 5(3 + 2) \ (2 * 3) = 25 \ 6 = 4 [wrong answer!]
^^^
This must be wrong
I'm not trying to make the claim that there doesn't exist some identity similar to this that is correct.