Обратно к битам

Тема в разделе "WASM.BEGINNERS", создана пользователем catangens, 24 сен 2005.

  1. catangens

    catangens New Member

    Публикаций:
    0
    Регистрация:
    11 сен 2005
    Сообщения:
    25
    Пишу на делфи, но обращаюсь сюда потому, что тут народу спривычнее работать с битами.

    Так вот:

    есть у меня последовательность

    байт со значениями 1,2,3 ..., 20

    n - это количество байт в put_n ( 20 )

    x - это число бит, которые необходимо оставить



    теперь

    с помошью строки

    for j:=1 to length(put_n) do put_n[j]:=put_n[j] shl (8-x);

    я сдвигаю биты влево чтобы оставить только нужные мне (их число x), просто так мне кажется проше работать

    теперь:

    f:=0;

    r:= ? ;

    j:=1;

    k:=1;

    while (j <= length(put_n)) do

    begin

    put_nnn[k]:=put_nnn[k] or (put_n[j] shl f);

    inc(f, ? ); if f = ? then f:=0;

    inc(j); if j > length(put_n) then break;

    put_nnn[k]:=put_nnn[k] or (put_n[j] shr r);

    inc(k);

    dec(r, ? ); if r = 0 then r:= ? ;

    end;



    вместо вопросительных знаков нужно подобрать такие значения чтобы при

    x=7

    получился ряд бит

    00000010 00000100 00000110 00001000 ...

    то есть последний восьмой бит не должен нести информации.

    при

    x=6

    00000100 00010000 00110000 ...

    опятьже последний восьмой бит во всех байтах не несет информации, а оставшиеся невостребованные биты седьмые несут информацию из следуюшего байта

    ещё пример при

    x=5

    00001000 01000010 10000000 ...

    здесь занимаются уже 6 и 7 биты для следующего байта



    так вот вместо вопросительных знаков нужно подобрать или вычислить значения которые при x от 1 до 7 (а лучше если сможите до 8 и больше) давалибы требуемый результат
     
  2. catangens

    catangens New Member

    Публикаций:
    0
    Регистрация:
    11 сен 2005
    Сообщения:
    25
    Попробую объяснить проше:

    есть у меня байты 1,2... 20 (к примеру 20 будет приделом)

    в битах это выглядит так

    00000001 00000010 00000011 ...



    Есть из восьми бит в байте "полезные", их количесво x

    например если х=5 то полезными будут:

    00001 00010 00011 ...



    теперь мне нужно записать только полезные биты в последовательность байт (получится некое сжатие), но в этих байтах восьмой бит не рабочий, то есть не должен нести информации



    то есть выходные байты должны быть следуюшими

    00001000 01000010 1...

    разбераем:

    первые 5 бит первого байта - это пять рабочих бит,

    следующие два первого байта - это два рабочих от (00010),

    восьмой бит не рабочий и не несет информации



    первые три бита второго байта - это последние три бита рабочих от (00010)

    следуюшие четыре бита вторго байта - это четыре рабочих бита от (00011)

    восьмой бит не рабочий и не несет информации



    первый бит третъего байта - это оставшийся бит от (00011)

    ...





    так вот: нужно составить кусок программы, которая бы при заданном х выводила из

    00000001 00000010 00000011 ...

    вот это

    00001000 01000010 1... (здесь для х=5)
     
  3. CrazyFun

    CrazyFun New Member

    Публикаций:
    0
    Регистрация:
    26 сен 2005
    Сообщения:
    129
    попробуй ассемблерную вставку:



    ;x - исходная послед. байтов (var x:array[1..strleng] of byte)

    ;y - послед.-приёмик

    ;n - кол-во значащих битов

    ;strleng - кол-во битов в x

    ;n и strleng - лучше литеральные константы(циферки)

    ;возможно командой pop надо сохранить нек. регистры

    ;(какие написано в справке о асм-вставках)



    xor ecx,ecx

    xor eax,eax

    xor edx,edx

    lea ebx,x

    lea esi,y

    kk:

    bt [ebx],eax

    jc zz

    btr [esi],edx

    imp zzz

    zz:

    bts [esi],edx

    zzz:



    inc edx

    inc eax

    cmp edx,7

    jnz aa

    btr [esi],edx

    xor edx,edx

    inc esi

    aa:

    cmp eax,n

    jnz aaa

    inc ecx

    cmp ecx,strleng

    jz en

    xor eax,eax

    inc ebx

    aaa:

    jmp kk



    en:



    ;поправлено,вроде даже работает
     
  4. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    catangens

    Такое ощущение, что у тебя путанница с последовательностью бит\байт и первый (нулевой) бит ты почему-то называешь 8-м ?

    Если загрузить 4 исходных байта в регистр, то в обычной нотации (МЗБ справа) это будет выглядеть так

    00000100 00000011 00000010 00000001

    Поэтому вроде как и упаковку логичнее делать путем сдвига в сторону младших битов:

    - оставляем по 5 бит: xxxx 00100 00011 00010 00001

    - вставляем каждый 8й: xx001000 00011000 01000001

    Как видишь ничего общего с твоими байтами, т.к. ты сдвигаешь биты не вниз, а вверх и вставляешь старшие биты следующего байта(байтов) в младшие биты предыдущего - имхо как-то шиворот-навыворот ;) Для чего такая мешанина, чтобы враг не догадался ?
     
  5. CrazyFun

    CrazyFun New Member

    Публикаций:
    0
    Регистрация:
    26 сен 2005
    Сообщения:
    129
    да кстати писал прогу исходя из цели задачи по памяти(не имея все примеры catangins'a пред глазами) так что должно вставляться по методу leo(однако не тестил).

    т.е.

    00000001 00000010 00000011 поидее перейдет в



    01000001 00011000 *******0



    сложность алгоритма помогает уберечь его от конкурентов(помню лицензию к винрар - заперещается востанавливать алгоритм бла бла)



    со сдвигами видимо было бы быстрее и возможно проже(однако мне пришла идея с перебором битов. каждый раз обращаться к памяти конечно дольше чем двигать регистры)

    ещё о сдвиге, чтобы не вставлять бит можно учитывать то что кол-во вставляемых битов в каждый байт периодически повторяется и зависит от кол-ва значащих битов.