解释代码的位操作部分
Explain the bit operations part of the code
此代码是解码 base64 字符串的实现。请解释代码的位操作部分。
frombase64(s): \base64_decode
b64s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
b64p = "="
ret = ""
s2 = s.replace(b64p, "")
left = 0
for i in range(0, len(s2)):
if left == 0:
left = 6
else:
value1 = b64s.index(s2[i - 1]) & (2 ** left - 1)
value2 = b64s.index(s2[i]) >> (left - 2)
value = (value1 << (8 - left)) | value2
ret += chr(value)
left -= 2
return ret
我有点新手programming.I不明白为什么要对变量value1、value2、value进行操作。我想了解这些操作如何将 base64 编码的字符串转换为文本。这是我从 here 拿来的。
我的问题是"what is happening in the else part of the code?"
如果您想知道代码的作用,让它告诉您
b64s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
b64p = "="
ret = ""
s2 = """TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlzIHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2YgdGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGludWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRoZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4=""".replace(b64p, "")
left = 0
for i in range(0, len(s2)):
if left == 0:
left = 6
else:
value1 = b64s.index(s2[i - 1]) & (2 ** left - 1)
value2 = b64s.index(s2[i]) >> (left - 2)
value = (value1 << (8 - left)) | value2
print(left, chr(value), bin(ord(s2[i-1])).rjust(10), bin(ord(s2[i])).rjust(10), bin(value1).rjust(10), bin(value2).rjust(10), bin(value).rjust(10))
ret += chr(value)
left -= 2
print(ret)
注意 (2 ** left - 1)
可能是 ((1<<left)-1)
。这将是一个位掩码(左 = 3,然后 0111 是生成的二进制文件)
我们想从s2[i-1]
中取出一些最右边的位,将它们与s2[i]
中的一些最左边的位组合,其中s2[i]
的剩余位将在下一次迭代中使用
回复你的评论..每个字符代表6位而不是8位。所以你需要组合2个字符来代表8位。 left -= 2 是因为 8-6 是 2。如果每个字符都是 4 位,那么您将 left 设置为 4 并减去 4,使 left == 0 每 2 次迭代触发一次。因为每对字符都将精确映射到 1 个字节。您只有 right/left 的滑动量,总和为 8。每次迭代都会滑动,因为您只需读取每个位一次,因此您需要将位索引滑动到读取的位之后。尝试将 left 想象成 i 的一部分,它索引位值。当 left 为 0 时,我们需要从当前字符中取出所有 6 并从下一个字符中取出 2,因此我们将 left 设置为 6 并继续到下一个字符,我们将从它中取出 4 并从前一个字符中取出 2(我们从上次迭代中取出 6 个)
此代码是解码 base64 字符串的实现。请解释代码的位操作部分。
frombase64(s): \base64_decode
b64s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
b64p = "="
ret = ""
s2 = s.replace(b64p, "")
left = 0
for i in range(0, len(s2)):
if left == 0:
left = 6
else:
value1 = b64s.index(s2[i - 1]) & (2 ** left - 1)
value2 = b64s.index(s2[i]) >> (left - 2)
value = (value1 << (8 - left)) | value2
ret += chr(value)
left -= 2
return ret
我有点新手programming.I不明白为什么要对变量value1、value2、value进行操作。我想了解这些操作如何将 base64 编码的字符串转换为文本。这是我从 here 拿来的。
我的问题是"what is happening in the else part of the code?"
如果您想知道代码的作用,让它告诉您
b64s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
b64p = "="
ret = ""
s2 = """TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlzIHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2YgdGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGludWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRoZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4=""".replace(b64p, "")
left = 0
for i in range(0, len(s2)):
if left == 0:
left = 6
else:
value1 = b64s.index(s2[i - 1]) & (2 ** left - 1)
value2 = b64s.index(s2[i]) >> (left - 2)
value = (value1 << (8 - left)) | value2
print(left, chr(value), bin(ord(s2[i-1])).rjust(10), bin(ord(s2[i])).rjust(10), bin(value1).rjust(10), bin(value2).rjust(10), bin(value).rjust(10))
ret += chr(value)
left -= 2
print(ret)
注意 (2 ** left - 1)
可能是 ((1<<left)-1)
。这将是一个位掩码(左 = 3,然后 0111 是生成的二进制文件)
我们想从s2[i-1]
中取出一些最右边的位,将它们与s2[i]
中的一些最左边的位组合,其中s2[i]
的剩余位将在下一次迭代中使用
回复你的评论..每个字符代表6位而不是8位。所以你需要组合2个字符来代表8位。 left -= 2 是因为 8-6 是 2。如果每个字符都是 4 位,那么您将 left 设置为 4 并减去 4,使 left == 0 每 2 次迭代触发一次。因为每对字符都将精确映射到 1 个字节。您只有 right/left 的滑动量,总和为 8。每次迭代都会滑动,因为您只需读取每个位一次,因此您需要将位索引滑动到读取的位之后。尝试将 left 想象成 i 的一部分,它索引位值。当 left 为 0 时,我们需要从当前字符中取出所有 6 并从下一个字符中取出 2,因此我们将 left 设置为 6 并继续到下一个字符,我们将从它中取出 4 并从前一个字符中取出 2(我们从上次迭代中取出 6 个)