Python 在 C 中生成的字符串
Python Generated String in C
我需要在 C 中生成以下字符串:
$(python -c "print('\x90' * a + 'blablabla' + '\x90' * b + 'h\xef\xff\xbf')")
其中 a 和 b 是任意整数,blablabla 代表任意字符串。我试图通过首先创建
来做到这一点
char str1[size];
然后做:
for (int i = 0; i < a; i+=1) {
strcat(str1, "\x90");
}
接下来我再次使用strcat:
strcat(str1, "blablabla");
并且我再次 运行 循环,这次 b
次,以连接下一个 b
x90
个字符。最后,我再次使用 strcat 如下:
strcat(str1, "h\xef\xff\xbf");
然而,这两个字符串不匹配。有没有一种更有效的方法可以在 C 中复制 python 的 *
的行为?还是我遗漏了什么?
对于单个 1 字节字符,您可以使用 memset
来部分复制 Python 的 *
:
的行为
#include<stdio.h>
#include<string.h>
int main(void){
char buffer[100];
memset(buffer,'#',10);
buffer[10] = '[=10=]';
printf("%s\n",buffer);
memset(buffer, '*', 5);
buffer[5] = '[=10=]';
printf("%s\n",buffer);
return 0;
}
输出:
##########
*****
有关更强大的解决方案,请参阅 this。
char str1[size];
即使假设您正确计算了大小,我也建议使用
char * str = malloc(size);
无论哪种方式,在以一种或另一种方式获得字符串所需的内存之后,您都必须先通过以下方式初始化它
str[0]=0;
如果您打算使用 strcat
。
for (int i = 0; i < a; i+=1) {
strcat(str1, "\x90");
}
这很有用,如果 "\x90"
实际上是一个字符串(即由多个字符组成的东西)并且 该字符串是 short(很难给出一个硬边界,但大约 16 个字节是顶部) 和 a
相当小 [1]。在这里,正如 John Coleman 已经建议的那样,memset
是更好的方法。
memset(str, '\x90', a);
因为您知道 "blablabla"
的存储位置,所以只需使用 strcpy
而不是 strcat
将其存储在那里
// strcat(str1, "blablabla");
strcpy(str + a, "blablabla");
但是,您需要 "blablabla"
之后字符的地址(无论哪种方式)。所以我什至不会那样做,而是这样:
const char * add_str = "blablabla";
size_t sl = strlen(add_str);
memcpy(str + a, add_str, sl);
然后,使用另一个 memset
:
而不是第二个循环
memset(str + a + sl, '\x90', b);
最后但同样重要的是,再次 strcpy
代替 strcat
更好(这里,memcpy
没有帮助):
strcpy(str + a + sl + b, "h\xef\xff\xbf");
但是你需要它的大小来开始计算大小,所以最好还是像 blablabla 字符串那样做(记住尾部 '[=35=]'
)。
最后,我会将所有这些代码放入一个函数中,如下所示:
char * gen_string(int a, int b) {
const char * add_str_1 = "blablabla";
size_t sl_1 = strlen(add_str_1);
const char * add_str_2 = "h\xef\xff\xbf";
size_t sl_2 = strlen(add_str_2);
size_t size = a + sl_1 + b + sl_2 + 1;
// The + 1 is important for the '[=19=]' at the end
char * str = malloc(size);
if (!str) {
return NULL;
}
memset(str, '\x90', a);
memcpy(str + a, add_str_1, sl_1);
memset(str + a + sl_1, '\x90', b);
memcpy(str + a + sl_1 + b, add_str_2, sl_2);
str[a + sl_1 + b + sl_2] = 0; // 0 is the same as '[=19=]'
return str;
}
记得 free()
在某些时候重装 gen_string
。
如果 memset
和 memcpy
调用列表变长,那么我建议这样做:
char * ptr = str;
memset(ptr, '\x90', a ); ptr += a;
memcpy(ptr, add_str_1, sl_1); ptr += sl_1;
memset(ptr, '\x90', b ); ptr += b;
memcpy(ptr, add_str_2, sl_2); ptr += sl_2;
*ptr = 0; // 0 is the same as '[=20=]'
甚至可以为 memset
和 memcpy
创建一个宏:
#define MEMSET(c, l) do { memset(ptr, c, l); ptr += l; } while (0)
#define MEMCPY(s, l) do { memcpy(ptr, s, l); ptr += l; } while (0)
char * ptr = str;
MEMSET('\x90', a );
MEMCPY(add_str_1, sl_1);
MEMSET('\x90', b );
MEMCPY(add_str_2, sl_2);
*ptr = 0; // 0 is the same as '[=21=]'
#undef MEMSET
#undef MEMCPY
关于为什么按照我推荐的方式去做的理由,我建议你阅读博客 post Back to Basics(Stack Overflow 的创始人之一),它不仅是John Coleman 最喜欢的博客 post 也是我的。在那里你会了解到,在循环中使用 strcat
就像你第一次尝试的那样有二次 运行 时间,因此,为什么不按照你的方式使用它。
[1]如果a
大and/or需要重复的字符串很长,更好的解决方案是这样的:
const char * str_a = "\x90";
size_t sl_a = strlen(str_a);
char * ptr = str;
for (size_t i = 0; i < a; ++i) {
strcpy(ptr, str_a);
ptr += sl_a;
}
// then go on at address str + a * sl_a
我需要在 C 中生成以下字符串:
$(python -c "print('\x90' * a + 'blablabla' + '\x90' * b + 'h\xef\xff\xbf')")
其中 a 和 b 是任意整数,blablabla 代表任意字符串。我试图通过首先创建
来做到这一点char str1[size];
然后做:
for (int i = 0; i < a; i+=1) {
strcat(str1, "\x90");
}
接下来我再次使用strcat:
strcat(str1, "blablabla");
并且我再次 运行 循环,这次 b
次,以连接下一个 b
x90
个字符。最后,我再次使用 strcat 如下:
strcat(str1, "h\xef\xff\xbf");
然而,这两个字符串不匹配。有没有一种更有效的方法可以在 C 中复制 python 的 *
的行为?还是我遗漏了什么?
对于单个 1 字节字符,您可以使用 memset
来部分复制 Python 的 *
:
#include<stdio.h>
#include<string.h>
int main(void){
char buffer[100];
memset(buffer,'#',10);
buffer[10] = '[=10=]';
printf("%s\n",buffer);
memset(buffer, '*', 5);
buffer[5] = '[=10=]';
printf("%s\n",buffer);
return 0;
}
输出:
##########
*****
有关更强大的解决方案,请参阅 this。
char str1[size];
即使假设您正确计算了大小,我也建议使用
char * str = malloc(size);
无论哪种方式,在以一种或另一种方式获得字符串所需的内存之后,您都必须先通过以下方式初始化它
str[0]=0;
如果您打算使用 strcat
。
for (int i = 0; i < a; i+=1) {
strcat(str1, "\x90");
}
这很有用,如果 "\x90"
实际上是一个字符串(即由多个字符组成的东西)并且 该字符串是 short(很难给出一个硬边界,但大约 16 个字节是顶部) 和 a
相当小 [1]。在这里,正如 John Coleman 已经建议的那样,memset
是更好的方法。
memset(str, '\x90', a);
因为您知道 "blablabla"
的存储位置,所以只需使用 strcpy
而不是 strcat
// strcat(str1, "blablabla");
strcpy(str + a, "blablabla");
但是,您需要 "blablabla"
之后字符的地址(无论哪种方式)。所以我什至不会那样做,而是这样:
const char * add_str = "blablabla";
size_t sl = strlen(add_str);
memcpy(str + a, add_str, sl);
然后,使用另一个 memset
:
memset(str + a + sl, '\x90', b);
最后但同样重要的是,再次 strcpy
代替 strcat
更好(这里,memcpy
没有帮助):
strcpy(str + a + sl + b, "h\xef\xff\xbf");
但是你需要它的大小来开始计算大小,所以最好还是像 blablabla 字符串那样做(记住尾部 '[=35=]'
)。
最后,我会将所有这些代码放入一个函数中,如下所示:
char * gen_string(int a, int b) {
const char * add_str_1 = "blablabla";
size_t sl_1 = strlen(add_str_1);
const char * add_str_2 = "h\xef\xff\xbf";
size_t sl_2 = strlen(add_str_2);
size_t size = a + sl_1 + b + sl_2 + 1;
// The + 1 is important for the '[=19=]' at the end
char * str = malloc(size);
if (!str) {
return NULL;
}
memset(str, '\x90', a);
memcpy(str + a, add_str_1, sl_1);
memset(str + a + sl_1, '\x90', b);
memcpy(str + a + sl_1 + b, add_str_2, sl_2);
str[a + sl_1 + b + sl_2] = 0; // 0 is the same as '[=19=]'
return str;
}
记得 free()
在某些时候重装 gen_string
。
如果 memset
和 memcpy
调用列表变长,那么我建议这样做:
char * ptr = str;
memset(ptr, '\x90', a ); ptr += a;
memcpy(ptr, add_str_1, sl_1); ptr += sl_1;
memset(ptr, '\x90', b ); ptr += b;
memcpy(ptr, add_str_2, sl_2); ptr += sl_2;
*ptr = 0; // 0 is the same as '[=20=]'
甚至可以为 memset
和 memcpy
创建一个宏:
#define MEMSET(c, l) do { memset(ptr, c, l); ptr += l; } while (0)
#define MEMCPY(s, l) do { memcpy(ptr, s, l); ptr += l; } while (0)
char * ptr = str;
MEMSET('\x90', a );
MEMCPY(add_str_1, sl_1);
MEMSET('\x90', b );
MEMCPY(add_str_2, sl_2);
*ptr = 0; // 0 is the same as '[=21=]'
#undef MEMSET
#undef MEMCPY
关于为什么按照我推荐的方式去做的理由,我建议你阅读博客 post Back to Basics(Stack Overflow 的创始人之一),它不仅是John Coleman 最喜欢的博客 post 也是我的。在那里你会了解到,在循环中使用 strcat
就像你第一次尝试的那样有二次 运行 时间,因此,为什么不按照你的方式使用它。
[1]如果a
大and/or需要重复的字符串很长,更好的解决方案是这样的:
const char * str_a = "\x90";
size_t sl_a = strlen(str_a);
char * ptr = str;
for (size_t i = 0; i < a; ++i) {
strcpy(ptr, str_a);
ptr += sl_a;
}
// then go on at address str + a * sl_a