我需要C中PHP函数ENT_COMPAT | ENT_HTML401
的默认行为(即htmlspecialchars()
),这在C中如何做得最好(这意味着最快)?
我不需要输入字符串,因此可以使用就地解决方案。
这是一个非常简单的功能,它只是转换这些字符:
'&' -> '&'
'"' -> '"'
'<' -> '<'
'>' -> '>'
哪种策略最快?单独循环每个字符并逐字节创建输出缓冲区,就地覆盖输入字符串或其他解决方案?
答案 0 :(得分:1)
此代码假定输入和输出是缓冲区,并且该输入包含输入字符串。它还假设输出缓冲区足够大以容纳输出(如果没有输出被截断):
long i = 0;
long j = 0;
while (input[i])
{
if (input[i] == '<')
{
memcpy(&output[j], "<", 4);
j += 4;
} else if (input[i] == '>')
{
memcpy(&output[j], ">", 4);
j += 4;
} else if (input[i] == '"')
{
memcpy(&output[j], """, 6);
j += 6;
} else if (input[i] == '&')
{
memcpy(&output[j], "&", 5);
j += 5;
} else
{
output[j++] = input[i];
}
if (j > sizeof(output)-7)
{
break;
}
i++;
}
output[j] = 0;
在C中,丑陋的代码通常是最快的。
如果要交换的字符非常非常罕见,那么就地解决方案只会产生性能优势,因此整个字符串可以在检测到的每个字符上重新排序(非常昂贵)。对于普通的HTML数据,这些4个字符经常出现,就地解决方案会慢得多。
答案 1 :(得分:1)
您可以构建适用于这两种情况的解决方案:
计算所需的空间并在传递NULL
时返回已分配的字符串,否则填充传递的字符串:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static size_t encode_len(const char *str)
{
size_t len = 0;
while (*str) {
if (*str == '"' || *str == '&' || *str == '<' || *str == '>') {
len += 5;
} else {
len += 1;
}
str++;
}
return len;
}
static char *encode(const char *str, char *dest)
{
char *ptr;
if (dest == NULL) {
dest = malloc(encode_len(str) + 1);
if (dest == NULL) return NULL;
}
ptr = dest;
while (*str) {
switch (*str) {
case '"': memcpy(ptr, """, 5); ptr += 5; break;
case '&': memcpy(ptr, "&", 5); ptr += 5; break;
case '<': memcpy(ptr, "<", 5); ptr += 5; break;
case '>': memcpy(ptr, ">", 5); ptr += 5; break;
default: *ptr++ = *str;
}
str++;
}
*ptr = *str;
return dest;
}
int main(void)
{
/* Returns an allocated string */
char *str = encode("testing & <> \"", NULL);
if (str) {
printf("%s\n", str);
free(str);
}
/* Fills a passed string */
char str2[128];
encode("testing & <> \"", str2);
printf("%s\n", str2);
return 0;
}
答案 2 :(得分:0)
这是 INT8
函数安全实现。
htmlspecialchars
是结果。
char *_output
是允许写入 size_t outlen
的最大字节数。
_output
是要进行 HTML 转义的字符串。
char *_input
是要转义的字符串长度(不包括空终止符)。
此函数返回写入 size_t inlen
的字节数,包括空终止符。
注意:此函数始终将空终止符放在 _output
中。
_output