AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / unix / Perguntas / 527905
Accepted
SurpriseDog
SurpriseDog
Asked: 2019-07-02 10:02:28 +0800 CST2019-07-02 10:02:28 +0800 CST 2019-07-02 10:02:28 +0800 CST

Inverter o último byte de um arquivo?

  • 772

Eu gostaria de testar meu programa de hash invertendo um único byte no final de um arquivo sem modificar o carimbo de data/hora. Evitar que o timestamp mude é bastante fácil, mas como uso um utilitário unix para inverter o último byte do arquivo?

Por exemplo: xou o último byte com 0xFF (uma operação que é facilmente reversível)

awk text-processing
  • 3 3 respostas
  • 673 Views

3 respostas

  • Voted
  1. ilkkachu
    2019-07-02T12:22:11+08:002019-07-02T12:22:11+08:00

    Não sed, mas isso parece funcionar em Perl:

    perl -pe 's/.\z/ $& ^ "\xff" /es if eof'  < in > out
    

    Ele lê por linhas, mas isso não importa, pois é limpo de 8 bits. eofé true na última linha e \zcorresponde ao final bruto da string ( $também corresponderia antes de uma nova linha final opcional, portanto, não estritamente no último byte). A substituição é apenas a operação xor na string correspondente.

    • 2
  2. Best Answer
    SurpriseDog
    2019-07-02T11:50:20+08:002019-07-02T11:50:20+08:00

    Eu mesmo fiz isso em python:

    python3 -c "import os, sys; name = sys.argv[1]; info = os.stat(name); f=open(sys.argv[1], 'rb+'); f.seek(-1,2); b = f.read(1)[0] ^ 0xFF; f.seek(-1,2); f.write(bytes([b])); print('Writing:', bytes([b])); os.utime(name, (info.st_atime, info.st_mtime))" filename
    

    Não é a solução mais elegante, mas tenho certeza de que vocês têm algum truque engenhoso de sed e podem fazê-lo melhor.

    Aqui está a versão completa, você pode executar com ./invert.py (nome do arquivo)

    import os, sys
    
    name = sys.argv[1]
    info = os.stat(name)
    
    with open(name, 'rb+') as f:
        f.seek(-1,2)
        b = f.read(1)[0] ^ 0xFF
        f.seek(-1,2)
        f.write(bytes([b]))
        print('Writing:', bytes([b]))
        os.utime(name, (info.st_atime, info.st_mtime))
    
    • 1
  3. LL3
    2019-07-02T15:59:27+08:002019-07-02T15:59:27+08:00

    Ferramentas como sede awkgeralmente não são adequadas para buscar arquivos ou manipular o conteúdo de um arquivo no nível de byte. Eles são orientados por linha, querem regexps ou números de linha como endereços e não têm nenhuma maneira (embutida) de recuperar os metadados de um arquivo, como, por exemplo, seu tamanho ou carimbos de data e hora.

    É possível alcançar o resultado pretendido também por meio de ferramentas de linha de comando, mas, até onde posso conceber, você precisa executar operações de "cola" em qualquer caso.

    Aqui está minha tentativa, apenas por diversão: ( em uma única linha apenas para demonstração, conforme seu desejo )

    (set -e -- $(ls -l <file>); pos=$(($5 - 1)); asciicode=$(od -j "$pos" -t u1 -A n "$9"); invcode=$(printf '%02x' $((asciicode ^ 0xff))); printf "\\x${invcode}" | dd of="$9" obs="$pos" seek=1)
    

    Substitua <file>pelo nome do seu arquivo.

    Não é realmente um one-liner, como você pode ver. Eu fui até certo ponto para ser compatível com POSIX, mas mesmo sem isso não seria muito mais curto.

    Observe também que ele não cuida do carimbo de data/hora do arquivo. Para fazer isso com ferramentas de linha de comando, ficaria assim: ( desta vez dividido para legibilidade e explicação )

    (
    set -e -- $(ls -l <file>)  # <-- parsing 'ls' output generally is not a good move
    pos=$(($5 - 1))            # file's size from `ls -l`, minus 1 to point to last byte
    asciicode=$(od -j "$pos" -t u1 -A n "$9")  # 'od' can seek with '-j' option
    invcode=$(printf '%02x' $((asciicode ^ 0xff)))  # 8-bit value read by 'od' xor-ed
                                                    # and made a 0-padded 2-digits hex value
    temp="$(mktemp)"                               # temporary helper file
    trap 'rm -f "$temp"' EXIT                      # dispose of it in due time
    touch -r "$9" "$temp"                          # copy original file's timestamp
    printf "\\x${invcode}" | dd of="$9" obs="$pos" seek=1  # put computed 8-bit value in place
    touch -r "$temp" "$9"                          # restore file's timestamp
    )
    

    Usando touch -r para frente e para trás em um arquivo temporário porque essa deve ser a maneira mais portátil de manter a precisão de nanossegundos.

    Pode ser bom observar também a necessidade de executar a operação arriscada de analisar lsa saída, mas não consigo pensar em outra ferramenta POSIX para recuperar o tamanho de um arquivo. Claro que neste caso poderia ser feito de uma forma mais segura (complicando ainda mais o script), mas essa necessidade pode ser mais uma dica de que estamos estendendo as ferramentas padrão um pouco além de suas tarefas pretendidas.

    • 1

relate perguntas

  • Reorganize as letras e compare duas palavras

  • Subtraindo a mesma coluna entre duas linhas no awk

  • Embaralhamento de arquivo de várias linhas

  • como posso alterar o caso do caractere (de baixo para cima e vice-versa)? ao mesmo tempo [duplicado]

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Possível firmware ausente /lib/firmware/i915/* para o módulo i915

    • 3 respostas
  • Marko Smith

    Falha ao buscar o repositório de backports jessie

    • 4 respostas
  • Marko Smith

    Como exportar uma chave privada GPG e uma chave pública para um arquivo

    • 4 respostas
  • Marko Smith

    Como podemos executar um comando armazenado em uma variável?

    • 5 respostas
  • Marko Smith

    Como configurar o systemd-resolved e o systemd-networkd para usar o servidor DNS local para resolver domínios locais e o servidor DNS remoto para domínios remotos?

    • 3 respostas
  • Marko Smith

    apt-get update error no Kali Linux após a atualização do dist [duplicado]

    • 2 respostas
  • Marko Smith

    Como ver as últimas linhas x do log de serviço systemctl

    • 5 respostas
  • Marko Smith

    Nano - pule para o final do arquivo

    • 8 respostas
  • Marko Smith

    erro grub: você precisa carregar o kernel primeiro

    • 4 respostas
  • Marko Smith

    Como baixar o pacote não instalá-lo com o comando apt-get?

    • 7 respostas
  • Martin Hope
    user12345 Falha ao buscar o repositório de backports jessie 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl Por que a maioria dos exemplos do systemd contém WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky Como exportar uma chave privada GPG e uma chave pública para um arquivo 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll status systemctl mostra: "Estado: degradado" 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim Como podemos executar um comando armazenado em uma variável? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S Por que /dev/null é um arquivo? Por que sua função não é implementada como um programa simples? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 Como ver as últimas linhas x do log de serviço systemctl 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - pule para o final do arquivo 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla Por que verdadeiro e falso são tão grandes? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis Substitua a string em um arquivo de texto enorme (70 GB), uma linha 2017-12-30 06:58:33 +0800 CST

Hot tag

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve