Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/64.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/ant/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
rawShift()何时可逆?_R - Fatal编程技术网

rawShift()何时可逆?

rawShift()何时可逆?,r,R,我可以安全地假设当我按1移位时,rawShift()总是可逆的,还是有需要注意的地方 例如: # convert a string to raw value starting_value <- 'here is a string' raw_value <- charToRaw(starting_value) # shift it, and get a new string shift_factor <- 1 shifted_raw <- rawShift(raw_val

我可以安全地假设当我按1移位时,
rawShift()
总是可逆的,还是有需要注意的地方

例如:

# convert a string to raw value
starting_value <- 'here is a string'
raw_value <- charToRaw(starting_value)

# shift it, and get a new string
shift_factor <- 1
shifted_raw <- rawShift(raw_value, shift_factor)
shifted_string <- rawToChar(shifted_raw)
shifted_string
# [1] "\xd0\xca\xe4\xca@\xd2\xe6@\xc2@\xe6\xe8\xe4\xd2\xdc\xce"

# reverse the process on the new string to get the original back
rawToChar(rawShift(charToRaw(shifted_string), -shift_factor))
# [1] "here is a string"
#将字符串转换为原始值

起始值答案是你不能指望这是可逆的。当我们使用
rawShift
时,可以通过数字发生的变化来说明这一点

首先,考虑原始数字<代码> 0x01 ,它存储为一个8位字节。该字节中的位将是

00000001
。如果我们将其转换为R中的一个数字,则得到数字1:

as.numeric(as.raw(0x01))
#> [1] 1
当我们使用
rawShift
时,我们将所有位移到左边,因此如果我们使用移位因子,则
00000001
变为
00000010
,这是数字2的二进制表示:

as.numeric(rawShift(as.raw(1), 1))
#> [1] 2
如果我们想得到
10000000
,我们甚至可以将其移位7位,这是128位二进制:

as.numeric(rawShift(as.raw(1,7))
#> [1] 128
但是,如果我们尝试左移8个位置,则会发生以下情况:

as.numeric(rawShift(as.raw(1), 8))
#> [1] 0
我们的8位溢出了。二进制
1
从末尾弹出,留下所有零。这当然意味着,如果我们尝试将其右移回8个位置,我们将无法返回到1,因为溢出的1已消失

因此,我们可以完全反转值1上7个位置的左移:

rawShift(rawShift(as.raw(1), 7), -7)
#> [1] 01
但如果我们在第二个问题上尝试,我们将溢出,我们的过程将变得不可逆转:

rawShift(rawShift(as.raw(2), 7), -7)
[1] 00
现在,也有可能我们的人数只有一部分溢出。假设我们有数字3,它是二进制的
00000011
,我们左移了7位。我们的第一个将溢出,但第二个将向上移动到第一位。当我们试图倒班时,我们得到的是
1
,而不是
3

rawShift(rawShift(as.raw(3), 7), -7)
#> [1] 01
现在我们可以考虑你的信息。将其转换为raw时,第一个字符是“h”。在raw中,这是0x68,十六进制代码为104。在二进制中,它将是
01101000
。如果我们把它移到左边一个空间,没有任何东西溢出,因此它是可逆的。然而,如果我们把它向左移动两次,我们得到的是
10100000
,所以当我们把它向后移动时,我们得到的是
00101000
,或者40,在Ascii中是

这就解释了为什么不能安全地移动原始字节并返回原始消息

有一种方法可以解决这个问题,那就是利用数字以64位精度存储在R中的事实,这样您就可以安全地转换为整数,左移任意多个位置(在合理范围内)并且能够反转。为此,我们使用
bitwshift
bitwshift
而不是
rawShift
。在这里,我将尝试在移位20位后恢复您的消息:

shifted <- bitwShiftL(as.numeric(charToRaw(starting_value)), 20)
shifted
#>  [1] 109051904 105906176 119537664 105906176  33554432 110100480 120586240  33554432
#>  [9] 101711872  33554432 120586240 121634816 119537664 110100480 115343360 108003328

rawToChar(as.raw(bitwShiftR(shifted, 20)))
#> [1] "here is a string"
shift[1]109051904 105906176 119537664 105906176 33554432 110100480 120586240 33554432
#>  [9] 101711872  33554432 120586240 121634816 119537664 110100480 115343360 108003328
rawToChar(原始(比特移位器(移位,20)))
#>[1]“这是一个字符串”

还有其他方法可以做到这一点,同时将所有内容都保留为8位字节,使用逐位运算符将高位环绕到低位,但我认为这个答案已经太长了……

对于我们下面的人来说,这种移位策略如何有用,在何处/何时可以使用?@Chris这种类型的移位有很多优点它是文件压缩、加密(这里最有可能的应用)的核心和快速的数学转换。它通常用于低级语言(如C),但在高级语言(如R)面向用户的部分(如R)中使用较少。在R中,它经常被抽象掉或由于调用开销而失去其计算优势。@AllanCameron,因此按元素的移位及其移位能力可能是取消移位/重移位的关键verse,密码意义上的。很好,明白了。有没有测试,测试包来测试这一数量的元素移位能力?@Chris请看我在答案下面的评论。你可以安全地将一个字节的前导零移位/反移位到与它的前导零相同的数量。01xxxxx可以移位/反移位100XXXXX到2,等等。1XXXXXX将溢出任何移位量的帮助l、 回答清楚,谢谢。简而言之,当rawShift被1移位导致二进制溢出时,它是不可逆的。因为基本ASCII字符(十六进制0到127)如果二进制值在00000000到01111010之间,则可以安全地按1移位并向后移位。但是,如果起始字符串可以包含二进制10000000及以上的值,则不安全。因此,我需要注意的边缘情况是:源字符串中的unicode!谢谢。(十进制0到127,我应该说。十六进制00到7F)