size_t的秘密

今天在看一个经典的双链表的时候看到了一个类型size_t,这个类型在此之前也经常见到,但是并没有太在意,一直都把他当成整形在用,但是在分析双链表的代码时发现了一个问题,跟我理解的有些出入,但是运行代码他的写法却是对的,于是就开始找我理解出错的地方,从头看了一遍,发现唯一的问题就是size_t类型,上网搜索了一下,讲解的并不多,一般都说把他当int用,于是自己写了一个代码测试下,代码如下:

#include <stdio.h>
int main()
{
size_t a=-1;
size_t b=90;
if (a<b)
printf("a bao chi bu bian/n");
else
printf("a bei bian yi wei bu ma/n");
}

运行结果为:

[root@localhost dry]# ./cc
a bei bian yi wei bu ma
调试看了下结果如下:

[root@localhost dry]# gdb cc
GNU gdb Fedora (6.8-29.fc10)
Copyright (C) 2008 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i386-redhat-linux-gnu"...
(gdb) list
1 #include <stdio.h>
2 int main()
3 {
4 size_t a=-1;
5 size_t b=90;
6 if (a<b)
7 printf("a bao chi bu bian/n");
8 else
9 printf("a bei bian yi wei bu ma/n");
10 }
(gdb) b 6
Breakpoint 1 at 0x80483d3: file cc.c, line 6.
(gdb) run
Starting program: /home/spexamples/1/5/dry/cc

Breakpoint 1, main () at cc.c:6
6 if (a<b)
Missing separate debuginfos, use: debuginfo-install glibc-2.9-2.i686
(gdb) print a
$1 = 4294967295
(gdb) print b
$2 = 90
(gdb) s
9 printf("a bei bian yi wei bu ma/n");
(gdb) s
a bei bian yi wei bu ma
10 }
由此可以看出,在编译的过程中size_t类型的a值会被编译他的补码。所以在使用size_t类型数据的过程中尤其要注意,特别是在逻辑表达式中使用到该类型,稍不注意可能带来很严重的后果。

注:正数的补码:与原码相同;负数的补码:符号位为1,其余位为该数绝对值的原码按位取反,然后整个数加1

 

uint32_t extracted_length; fread(&extracted_length, sizeof(uint32_t), 1, input_file); extracted_length = ntohl(extracted_length);提取代码也加入上面代码,进行修改std::string f5ExtractColorImage(cv::Mat& img) { // 转换到YCrCb颜色空间 cv::Mat yuv_image; cv::cvtColor(img, yuv_image, cv::COLOR_BGR2YCrCb); std::vector<cv::Mat> channels; cv::split(yuv_image, channels); cv::Mat y_channel = channels[0].clone(); // 生成块坐标并洗牌(必须与嵌入时相同的随机逻辑) const int block_size = 8; std::vector<cv::Point> blocks; for (int y = 0; y < y_channel.rows; y += block_size) { for (int x = 0; x < y_channel.cols; x += block_size) { blocks.emplace_back(x, y); } } std::mt19937 rng(12345); // 固定种子确保洗牌顺序一致 std::shuffle(blocks.begin(), blocks.end(), rng); std::string extracted_bits; // 遍历每个块提取信息 for (const auto& block : blocks) { cv::Rect roi(block.x, block.y, block_size, block_size); if (roi.br().x > y_channel.cols || roi.br().y > y_channel.rows) continue; cv::Mat block_data = y_channel(roi).clone(); block_data.convertTo(block_data, CV_32F); // DCT变换 cv::Mat dct_coeffs; cv::dct(block_data, dct_coeffs); // 提取量化系数的LSB for (int i = 0; i < block_size; ++i) { for (int j = 0; j < block_size; ++j) { if (i == 0 && j == 0) continue; // 跳过直流分量 float q_val = QUANTIZATION_MATRIX.at<float>(i, j); float quantized = std::round(dct_coeffs.at<float>(i, j) / q_val); if (quantized == 0) continue; // 跳过未嵌入的系数 // 提取最低有效位 extracted_bits += (static_cast<int>(quantized) % 2) ? '1' : '0'; } } } // 二进制转字符串 std::string secret_message; for (size_t i = 0; i < extracted_bits.size(); i += 8) { if (i + 8 > extracted_bits.size()) break; secret_message += static_cast<char>( std::bitset<8>(extracted_bits.substr(i, 8)).to_ulong() ); } // 移除可能存在的填充空字符 size_t null_pos = secret_message.find('\0'); return (null_pos != std::string::npos) ? secret_message.substr(0, null_pos) : secret_message; }提取代码也修改一下
03-27
// 嵌入时写入长度 std::string message = "hello"; uint32_t msg_length = htonl(message.size()); // 转换为网络字节序 fwrite(&msg_length, sizeof(uint32_t), 1, output_file); // 先写长度头 fwrite(message.data(), 1, message.size(), output_file); // 再写数据 // 提取时读取长度头 uint32_t extracted_length; fread(&extracted_length, sizeof(uint32_t), 1, input_file); extracted_length = ntohl(extracted_length); 将上面代码加入我下面代码中,再返回完整代码给我 void f5EmbedColorImage(cv::Mat& image, const std::string& secret_message) { // 转换秘密信息为二进制位序列 std::string secret_bits; for (char c : secret_message) { secret_bits += std::bitset<8>(c).to_string(); } // 转换到YCrCb颜色空间 cv::Mat yuv_image; cv::cvtColor(image, yuv_image, cv::COLOR_BGR2YCrCb); std::vector<cv::Mat> channels(3); cv::split(yuv_image, channels); cv::Mat& y_channel = channels[0]; const int block_size = 8; const int rows = y_channel.rows; const int cols = y_channel.cols; // 生成块坐标列表并洗牌 std::vector<cv::Point> blocks; for (int y = 0; y < rows; y += block_size) { for (int x = 0; x < cols; x += block_size) { blocks.emplace_back(x, y); } } std::random_device rd; std::shuffle(blocks.begin(), blocks.end(), std::mt19937(12345)); size_t bit_idx = 0; for (const auto& block : blocks) { if (bit_idx >= secret_bits.size()) break; cv::Rect roi(block.x, block.y, block_size, block_size); if (roi.x + roi.width > cols || roi.y + roi.height > rows) continue; cv::Mat block_data = y_channel(roi).clone(); block_data.convertTo(block_data, CV_32F); // DCT变换 cv::Mat dct_coeffs; cv::dct(block_data, dct_coeffs); // 量化和嵌入 for (int i = 0; i < block_size; ++i) { for (int j = 0; j < block_size; ++j) { if (i == 0 && j == 0) continue; // 跳过直流分量 // 量化 float q_val = QUANTIZATION_MATRIX.at<float>(i,j); float quantized = std::round(dct_coeffs.at<float>(i,j) / q_val); if (quantized == 0) continue; if (bit_idx >= secret_bits.size()) break; // 嵌入信息 int target_bit = secret_bits[bit_idx] - '0'; int current_bit = static_cast<int>(quantized) % 2; if (current_bit != target_bit) { quantized += (quantized > 0) ? -1 : 1; } // 反量化并更新系数 dct_coeffs.at<float>(i,j) = quantized * q_val; ++bit_idx; } } // 逆DCT cv::Mat idct_block; cv::idct(dct_coeffs, idct_block); idct_block.convertTo(idct_block, y_channel.type()); idct_block.copyTo(y_channel(roi)); } // 合并通道并转换回BGR cv::merge(channels, yuv_image); cv::cvtColor(yuv_image, image, cv::COLOR_YCrCb2BGR); }
03-27
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值