十六进制字符位旋转
Hex Character bit rotation
我编写了以下要在 C 程序中调用的 x86-64 函数:
第一个接受 2 位十六进制字符并将其位向右旋转一位,即,如果“12”(表示 0x12 但 0x 未作为输入提供)向右旋转一位以提供“09” (0x09)
.file "rotate_right.s"
.section .rodata
.data
.globl rotate_right
.type rotate_right, @function
.text
rotate_right:
pushq %rbp
movq %rsp,%rbp
pushq %rsi
pushq %rdi
pushq %rbx
subl , %esp
movb 8(%ebp), %al
sarb , %al
leave
ret
.size rotate_right, .-rotate_right
同样,此函数将位向左旋转一位,因此'12'(0x12) 变为'24'(0x24)。
.file "rotate_left.s"
.section .rodata
.data
.globl rotate_left
.type rotate_left, @function
.text
rotate_left:
pushq %rbp
movq %rsp,%rbp
pushq %rsi
pushq %rdi
pushq %rbx
subl , %esp
movb 8(%ebp), %al
sarb , %al
leave
ret
.size rotate_left, .-rotate_left
create_key() 函数获取一个四位输入,如 0110,并输出一个 8 位输出作为无符号整数,即 01100110:
.file "create_key.s"
.section .rodata
ask_key:
.string "Enter 4-bit key:"
.data
.globl create_key
.type create_key, @function
.text
create_key:
pushq %rbp
# stack holding
movq %rsp, %rbp
movl $ask_key, %edi
# printing the ask string
movl [=12=], %eax
# calling the C functions
call printf
movl [=12=],%esi
# rsi is set to 0. the key
pushq %rsi
# take it to the stack
# call getchar for getting each key bit
call getchar
popq %rsi
subl ,%eax
# doing this will give us 1 or 0 if the we input 1 or 0
sall ,%esi
# shift the key by one bit
orl %eax,%esi
# OR key and the sigle input
pushq %rsi
# push rsi to stack to save the value in rsi
# Do the above operation a total of 4 times
call getchar
popq %rsi
subl ,%eax
sall ,%esi
orl %eax,%esi
pushq %rsi
call getchar
popq %rsi
subl ,%eax
sall ,%esi
orl %eax,%esi
pushq %rsi
call getchar
popq %rsi
subl ,%eax
sall ,%esi
orl %eax,%esi
# copy first 4-bits of the key into %rax
movl %esi,%eax
#left shift the key 4 times
sall ,%esi
# OR the secont 4-bits into %rax
orl %esi,%eax
leave
ret
# return the values and end the function
.size create_key, .-create_key
这是C程序,
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<string.h>
extern unsigned int create_key();
extern unsigned char rotate_left(unsigned char x);
extern unsigned char rotate_right(unsigned char x);
int main(){
/* This Part Takes The Input To Be Ciphered
And Prints The Hexadecimal Value*/
char word[200], outword[400], xor_hex[400], hex_rot[400], ch, hex[2];
unsigned int i_key, encodant, rotated;
int i, len, j;
/* i_key is the integer equvivalent of the cipher key*/
printf("enter cleartext:");
i = 0;
ch = getchar();
while(ch!='\n'){
word[i] = ch;
++i;
ch = getchar();
}
fflush(stdin);
len = i;
word[i] = '[=13=]';
printf("%s\n", word);
printf("hex encoding:\n");
for(i = 0; i<len; i++){
sprintf(outword+(i*2), "%02X", word[i]);
}
for(i=0;i<(2*len);i++){
if(i%2==0 & i>0)printf(" ");
if(i%20==0 & i>0)printf("\n");
printf("%c", outword[i]);
}
printf("\n");
/* This Part Asks For The Cipher Key */
i_key = create_key();
/* XOR Encoding of the Hex Cyphertext*/
for(i=0;i<len*2;i+=2){
hex[0] = outword[i];
hex[1] = outword[i+1];
encodant = (int)strtol(hex, NULL, 16);
sprintf(xor_hex+(i), "%02X", (i_key^encodant));
}
/* Encoding the text using bit rotation */
j=1;
for(i=0;i<len*2;i+=2){
hex[0]=xor_hex[i];
hex[1]=xor_hex[i+1];
encodant = (int)strtol(hex, NULL, 16);
if(j%2==0)rotated = rotate_right(encodant);
else rotated = rotate_left(encodant);
j++;
sprintf(hex_rot+(i), "%02X", rotated);
}
/* Printing The Finished Ciphered Text */
printf("hex ciphertext:\n");
for(i=0;i<(2*len);i++){
if(i%2==0 & i>0)printf(" ");
if(i%20==0 & i>0)printf("\n");
printf("%c", hex_rot[i]);
}
printf("\n");
return 0;
}
不能更改函数原型,即旋转函数必须是 char 并且具有 char 参数,create_key 函数看起来不错,但我的代码给出了分段错误。我不知道在这种情况下该怎么做,所以感谢您的帮助。
这里不需要对栈做任何操作。从 rdi
(SysV) 或 rcx
(Win32) 中获取参数,将其放入 al
,旋转并 return:
.file "rotate.S"
.text
.globl rotate_right
rotate_right:
mov %rdi, %rax
shrb , %al
ret
.globl rotate_left
rotate_left:
mov %rdi, %rax
shlb , %al
ret
.end
现在是 GNU as
语法,可能需要针对 AT&T asm 进行一些调整。
测试一下:
#include <stdio.h>
unsigned char rotate_left(unsigned char);
unsigned char rotate_right(unsigned char);
int main() {
printf("%02x %02x\n", rotate_left(0x12), rotate_right(0x12));
return 0;
}
打印:
24 09
我编写了以下要在 C 程序中调用的 x86-64 函数: 第一个接受 2 位十六进制字符并将其位向右旋转一位,即,如果“12”(表示 0x12 但 0x 未作为输入提供)向右旋转一位以提供“09” (0x09)
.file "rotate_right.s"
.section .rodata
.data
.globl rotate_right
.type rotate_right, @function
.text
rotate_right:
pushq %rbp
movq %rsp,%rbp
pushq %rsi
pushq %rdi
pushq %rbx
subl , %esp
movb 8(%ebp), %al
sarb , %al
leave
ret
.size rotate_right, .-rotate_right
同样,此函数将位向左旋转一位,因此'12'(0x12) 变为'24'(0x24)。
.file "rotate_left.s"
.section .rodata
.data
.globl rotate_left
.type rotate_left, @function
.text
rotate_left:
pushq %rbp
movq %rsp,%rbp
pushq %rsi
pushq %rdi
pushq %rbx
subl , %esp
movb 8(%ebp), %al
sarb , %al
leave
ret
.size rotate_left, .-rotate_left
create_key() 函数获取一个四位输入,如 0110,并输出一个 8 位输出作为无符号整数,即 01100110:
.file "create_key.s"
.section .rodata
ask_key:
.string "Enter 4-bit key:"
.data
.globl create_key
.type create_key, @function
.text
create_key:
pushq %rbp
# stack holding
movq %rsp, %rbp
movl $ask_key, %edi
# printing the ask string
movl [=12=], %eax
# calling the C functions
call printf
movl [=12=],%esi
# rsi is set to 0. the key
pushq %rsi
# take it to the stack
# call getchar for getting each key bit
call getchar
popq %rsi
subl ,%eax
# doing this will give us 1 or 0 if the we input 1 or 0
sall ,%esi
# shift the key by one bit
orl %eax,%esi
# OR key and the sigle input
pushq %rsi
# push rsi to stack to save the value in rsi
# Do the above operation a total of 4 times
call getchar
popq %rsi
subl ,%eax
sall ,%esi
orl %eax,%esi
pushq %rsi
call getchar
popq %rsi
subl ,%eax
sall ,%esi
orl %eax,%esi
pushq %rsi
call getchar
popq %rsi
subl ,%eax
sall ,%esi
orl %eax,%esi
# copy first 4-bits of the key into %rax
movl %esi,%eax
#left shift the key 4 times
sall ,%esi
# OR the secont 4-bits into %rax
orl %esi,%eax
leave
ret
# return the values and end the function
.size create_key, .-create_key
这是C程序,
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<string.h>
extern unsigned int create_key();
extern unsigned char rotate_left(unsigned char x);
extern unsigned char rotate_right(unsigned char x);
int main(){
/* This Part Takes The Input To Be Ciphered
And Prints The Hexadecimal Value*/
char word[200], outword[400], xor_hex[400], hex_rot[400], ch, hex[2];
unsigned int i_key, encodant, rotated;
int i, len, j;
/* i_key is the integer equvivalent of the cipher key*/
printf("enter cleartext:");
i = 0;
ch = getchar();
while(ch!='\n'){
word[i] = ch;
++i;
ch = getchar();
}
fflush(stdin);
len = i;
word[i] = '[=13=]';
printf("%s\n", word);
printf("hex encoding:\n");
for(i = 0; i<len; i++){
sprintf(outword+(i*2), "%02X", word[i]);
}
for(i=0;i<(2*len);i++){
if(i%2==0 & i>0)printf(" ");
if(i%20==0 & i>0)printf("\n");
printf("%c", outword[i]);
}
printf("\n");
/* This Part Asks For The Cipher Key */
i_key = create_key();
/* XOR Encoding of the Hex Cyphertext*/
for(i=0;i<len*2;i+=2){
hex[0] = outword[i];
hex[1] = outword[i+1];
encodant = (int)strtol(hex, NULL, 16);
sprintf(xor_hex+(i), "%02X", (i_key^encodant));
}
/* Encoding the text using bit rotation */
j=1;
for(i=0;i<len*2;i+=2){
hex[0]=xor_hex[i];
hex[1]=xor_hex[i+1];
encodant = (int)strtol(hex, NULL, 16);
if(j%2==0)rotated = rotate_right(encodant);
else rotated = rotate_left(encodant);
j++;
sprintf(hex_rot+(i), "%02X", rotated);
}
/* Printing The Finished Ciphered Text */
printf("hex ciphertext:\n");
for(i=0;i<(2*len);i++){
if(i%2==0 & i>0)printf(" ");
if(i%20==0 & i>0)printf("\n");
printf("%c", hex_rot[i]);
}
printf("\n");
return 0;
}
不能更改函数原型,即旋转函数必须是 char 并且具有 char 参数,create_key 函数看起来不错,但我的代码给出了分段错误。我不知道在这种情况下该怎么做,所以感谢您的帮助。
这里不需要对栈做任何操作。从 rdi
(SysV) 或 rcx
(Win32) 中获取参数,将其放入 al
,旋转并 return:
.file "rotate.S"
.text
.globl rotate_right
rotate_right:
mov %rdi, %rax
shrb , %al
ret
.globl rotate_left
rotate_left:
mov %rdi, %rax
shlb , %al
ret
.end
现在是 GNU as
语法,可能需要针对 AT&T asm 进行一些调整。
测试一下:
#include <stdio.h>
unsigned char rotate_left(unsigned char);
unsigned char rotate_right(unsigned char);
int main() {
printf("%02x %02x\n", rotate_left(0x12), rotate_right(0x12));
return 0;
}
打印:
24 09