core :: Int :: unrail_paces
Each entry of the returned array is a couple of the first pace and the second one, they are alternated when deciphering a rail-encrypted string.
Say we have the encrypted string "fgounbmtcieehkh" on 4 rails
To find the distance between each character on the original railed string, we need to compute the extremes.
The extremes always have a distance of depth - 1
, multiplied by 2, no pairing.
In the example, that would be : [(4 - 1) * 2, (4 - 1) * 2] => [6,6]
For every rail in-between, the first distance is the largest absolute value of the difference between the current depth and the extremes, multiplied by 2.
Its pair is the distance of maximum and the distance yielded by the previous calculation.
In our example, that would be :
Maximums : (4 - 1) * 2 = 3 * 2 => [6,6] In between : Distance for depth 2 : max(2 - 1, 4 - 2) => 2 The calculation yields the couple [(2 * 2), 6 - 4] => [4, 2] The symmetric couple is reversed : [2, 4]
In fine, the example yields the array :
Error: No entity for 6,6
.
Did you mean:
In the end, our string is read using the generated array
SEE: Text::unrail
for how the array is used
# Generates the paces for each depth.
#
# Each entry of the returned array is a couple of the first pace
# and the second one, they are alternated when deciphering a rail-encrypted string.
#
# Say we have the encrypted string "fgounbmtcieehkh" on 4 rails
#
# To find the distance between each character on the original railed
# string, we need to compute the extremes.
#
# The extremes always have a distance of `depth - 1`, multiplied by 2, no pairing.
#
# In the example, that would be : [(4 - 1) * 2, (4 - 1) * 2] => [6,6]
#
# For every rail in-between, the first distance is the largest absolute value
# of the difference between the current depth and the extremes, multiplied by 2.
#
# Its pair is the distance of maximum and the distance yielded by the previous
# calculation.
#
# In our example, that would be :
#
# Maximums : (4 - 1) * 2 = 3 * 2 => [6,6]
# In between : Distance for depth 2 : max(2 - 1, 4 - 2) => 2
# The calculation yields the couple [(2 * 2), 6 - 4] => [4, 2]
# The symmetric couple is reversed : [2, 4]
#
# In fine, the example yields the array : [[6,6], [4,2], [2,4], [6,6]]
#
# In the end, our string is read using the generated array
#
# SEE: `Text::unrail` for how the array is used
private fun unrail_paces: Array[Couple[Int, Int]] do
var ret = new Array[Couple[Int,Int]].with_capacity(self)
var extremes = new Couple[Int, Int]((self - 1) * 2, (self - 1) * 2)
for i in [0..self[ do
ret.add extremes
end
var mid = ((self.to_f)/2.0).floor.to_i
for i in [1 .. mid[ do
var rd = i + 1
var lodepth = self - rd
var hidepth = (rd - self).abs
var dd: Int
if hidepth > lodepth then
dd = hidepth * 2
else
dd = lodepth * 2
end
var cp = new Couple[Int, Int](dd, extremes.first-dd)
var ccp = new Couple[Int, Int](extremes.first - dd, dd)
ret[i] = cp
ret[self - rd] = ccp
end
if not self.is_even then
ret[mid] = new Couple[Int, Int](extremes.first/2, extremes.first/2)
end
return ret
end
lib/crypto/basic_ciphers.nit:229,2--288,4