1

我有两个 for 循环,我想将它们写在一个函数中。问题是它仅在一条指令上有所不同

for (int i = 1; i <= fin_cabecera - 1 ; i++ ){
    buffer[i] &= 0xfe;
    if (bitsLetraRestantes < 0) {
        bitsLetraRestantes = 7;
        mask = 0x80;
        letra = sms[++indiceLetra]; //*differs here*
    }
    char c = (letra & mask) >> bitsLetraRestantes--;
    mask >>= 1;
    buffer[i] ^= c; 
}

和另外一个

for (int i = datos_fichero; i <= tamanio_en_bits + datos_fichero; i++){
    buffer[i] &= 0xfe;
    if (bitsLetraRestantes < 0) {
        bitsLetraRestantes = 7;
        mask = 0x80;
        f.read(&letra, 1);  //*differs here*
    }
    char c = (letra & mask) >> bitsLetraRestantes--;
    mask >>= 1;
    buffer[i] ^= c; 
}

我是这样想的:

void write_bit_by_bit(unsigned char buffer[], int from, int to, bool type) {
    for (int i = to; i <= from; i++) {
        buffer[i] &= 0xfe;
        if (bitsLetraRestantes < 0) {
            bitsLetraRestantes = 7;
            mask = 0x80;
            type ? (letra = sms[++indiceLetra]) : f.read(&letra, 1);
        }
        char c = (letra & mask) >> bitsLetraRestantes--;
        mask >>= 1;
        buffer[i] ^= c;
    }
}

但我认为必须有更好的方法。

语境:

我会给出更多的上下文(我会在我的语言限制范围内尽可能地解释它)。我每次都必须读取一个字节,因为该Buffer变量代表一个图像像素。sms是必须隐藏在图像中的消息,并且letra是该消息的单个字符。为了不修改图像的方面,每个字符的每一位都必须写入每个像素的最后一位。让我给你和例子。

letra = 'H' // 01001000 in binary

buffer[0] = 255 // white pixel 11111111

为了隐藏 H 字符,我需要 8 个像素:

结果将如下所示:

buffer[0] //11111110, 
buffer[1] //11111111 
buffer[2] //11111110 
buffer[3] //11111110 
buffer[4] //11111111 
buffer[5] //11111110 
buffer[6]//11111110 
buffer[7]//11111110

The H is hidden in the last bit of the image. I hope I explained well.

[Solution]

Thanks to @anatolyg I've rewrited the code and now works just as I wanted. Here is how it looks:

void write_bit_by_bit(unsigned char buffer[], ifstream& f,int from, int to, char sms[], bool type){

unsigned short int indiceLetra        = 0;
short int bitsLetraRestantes          = 7;
unsigned char mask                    = 0x80; //Empezamos por el bit más significativo (10000000)

char* file_buffer;

if(type){ //Write file data
    int number_of_bytes_to_read = get_file_size(f);
    file_buffer = new char[number_of_bytes_to_read];
    f.read(file_buffer, number_of_bytes_to_read);
}

const char* place_to_get_stuff_from = type ? file_buffer : sms;
char letra = place_to_get_stuff_from[0];

for (int i = from; i <= to; i++) {
    buffer[i] &= 0xfe; //hacemos 0 último bit con máscara 11111110
    //TODO: Hacer con dos for
    if (bitsLetraRestantes < 0) {
        bitsLetraRestantes = 7;
        mask = 0x80;
        letra = place_to_get_stuff_from[++indiceLetra];//letra = sms[++indiceLetra];
    }
    char c = (letra & mask) >> bitsLetraRestantes--;
    mask >>= 1;
    buffer[i] ^= c; //Almacenamos en el ultimo bit del pixel el valor del caracter
}
}

int ocultar(unsigned char buffer[],int tamImage, char sms[], int tamSms){
ifstream f(sms);
if (f) {
    strcpy(sms,basename(sms));
    buffer[0] = 0xff;
    int fin_cabecera = strlen(sms)*8 + 1;
    buffer[fin_cabecera] = 0xff;

    write_bit_by_bit(buffer, f, 1, fin_cabecera -1, sms, WRITE_FILE_NAME);

    int tamanio_en_bits = get_file_size(f) * 8;

    int datos_fichero = fin_cabecera + 1;
    write_bit_by_bit(buffer, f, datos_fichero, tamanio_en_bits + datos_fichero, sms, WRITE_FILE_DATA);

    unsigned char fin_contenido = 0xff;

    short int bitsLetraRestantes          = 7;
    unsigned char mask            = 0x80; 

    for (int i = tamanio_en_bits + datos_fichero + 1;
            i < tamanio_en_bits + datos_fichero + 1 + 8; i++) {
        buffer[i] &= 0xfe;
        char c = (fin_contenido & mask) >> bitsLetraRestantes--;
        mask >>= 1;
        buffer[i] ^= c; 
    }

}
return 0;
}
4

1 回答 1

2

Since you are talking about optimization here, consider performing the read outside the loop. This will be a major optimization (reading 10 bytes at once must be quicker than reading 1 byte 10 times). This will require an additional buffer for (the file?) f.

if (!type)
{
    char f_buffer[ENOUGH_SPACE];
    number = calc_number_of_bytes_to_read();
    f.read(f_buffer, number);
}
for (...) {
    // your code
}

After you have done this, your original question is easy to answer:

const char* place_to_get_stuff_from = type ? sms : f_buffer;
for (...) {
        ...
        letra = place_to_get_stuff_from[++indiceLetra];
        ...
}
于 2012-08-20T19:03:42.293 回答