Proteger um arquivo com zeros


12

Sua tarefa hoje será pegar um arquivo existente e anexar zeros a ele até atingir um determinado tamanho.

Você deve escrever um programa ou função que leve o nome de um arquivo no diretório atual fe um número de bytes b. Enquanto mantém o conteúdo original de f, você deve escrever zeros (bytes nulos, não ascii 0s) até o fim, para que seu novo tamanho seja bbytes.

Você pode assumir que fapenas possui ascii alfanuméricos em seu nome, que possui permissões totais sobre ele, que inicialmente não é maior que b, mas pode ser tão grande quanto b, e que há espaço livre em disco infinito.

Você não pode assumir que não festá vazio ou que ainda não contém bytes nulos.

Outros arquivos existentes não devem ser modificados e novos arquivos não devem existir após o término da execução.

Casos de teste

Conteúdo de f | b Conteúdo resultante de f
12345 10 1234500000
0 3 000
[vazio] | 2 00
[vazio] | 0 [esvaziar]
123 3 123

@totallyhuman inicialmente não é maior do que #b
— Adám

Podemos pegar o conteúdo do arquivo como entrada e gerar o conteúdo modificado?
— Shaggy

Podemos usar bibliotecas?
— Adám

1
@ Phoenix O problema é que Dennis colocou a biblioteca em uma pasta distante (não é minha escolha). Posso contar como se estivesse disponível no caminho de pesquisa?
— Adám

Podemos assumir que o arquivo ainda não conterá bytes nulos?
— Dom Hastings

Respostas:


20

Bash + coreutils, 13

truncate -s$@

Entrada da linha de comando - o primeiro parâmetro é o tamanho do arquivo e o segundo é o nome do arquivo.

De man truncate:

Se um ARQUIVO for mais curto, ele será estendido e a parte estendida (furo) será lida como zero bytes.

Experimente online .


1
O truncado também pode se estender?
— Adám

11
Um homem que conhece o seu homem em um homem viril, de fato.
— Magic Octopus Urn

Gostaria de saber se funciona em uma partição FAT, onde o truncatesyscall falha.
— Matteo Italia

1
Minha implementação da mesma ideia teria sido dd bs=1 of=$1 seek=$2<&-(que imprime uma mensagem de erro que pode ser ignorada). O seu é muito mais curto. Agradável.
— hvd 10/06

@hvd sim eu dd figurado provavelmente poderia fazer isso
— Digital Trauma

4

Groovy, 54 47 43 41 bytes

{a,b->(c=new File(a))<<'\0'*(b-c.size())}

-6 graças à idéia do manatwork de remover o loop; essa foi a minha ideia original, não sei por que pensei que não iria funcionar e optei por um loop ... Definitivamente funciona, apenas testei.

Ungolfed:

{
    a,b->                    // Two inputs: a is the File name, b is the desired size.
    File c = new File(a)     // Make and store the file.
    c << '\0'*(b-c.size())   // Append the difference between b and c.size() in nullbytes.
}
                             // Usually a close would be required, but, in Groovy,
                             // because private data isn't so protected, if a File
                             // Object goes out of scope, the attached Stream is 
                             // automatically flushed to disk.

1
Não seria mais curto sem loop? {a,b->c=new File(a);c<<('\0'*(b-c.size()))}
— manatwork

@manatwork yeah! E na verdade pode ser ainda melhor que isso.
— Magic Octopus Urn

@manatwork deixa pra lá, o mesmo valor por (c=new File(a))devido aos parênteses necessários.
— Magic Octopus Urn

1
Não faço ideia por que coloque parênteses em torno de todo o valor a acrescentar. Não é necessário.
— manatwork

@manatwork Groovy é bastante temperamental quanto aos parênteses, não posso te culpar haha.
— Magic Octopus Urn


3

Python 2 , 59 57 54 bytes

-5 bytes graças ao chepner

def g(n,b):f=open(n,'a');f.write('\0'*b);f.truncate(b)

1
@totallyhuman \x00é um byte nulo.
— Pavel

1
@totallyhuman não, é mais como uma coisa bandeira (para interactino disallow com arquivos fechados)
— Rod

1
@ Rod Eu amo interactino! Melhor jogo para crianças interativo sempre
— Caird coinheringaahing

Você pode usar \0no lugar de \x00.
— chepner

Você pode salvar mais três bytes por overextending, em seguida, truncando: def g(n,b):f=open(n,'a');f.write('\0'*b);f.truncate(b).
— chepner

3

PHP, 66 bytes

for($p=fopen($f=$argv[1],a);filesize($f)<$argv[2];)fputs($p,"\0");

Recebe entrada dos argumentos da linha de comando; corra com -nr.


Esses 55 bytes podem, mas provavelmente não funcionarão:

fseek($p=fopen($argv[1],"w+"),$argv[2]);fputs($p,"\0");

2

Java (Oracle JRE), 55 bytes

f->b->new java.io.RandomAccessFile(f,"rw").setLength(b)

A especificação de setLength(int)diz que os bytes anexados são indefinidos, mas praticamente o Oracle JRE acrescenta apenas o 0byte (foi por isso que eu o especifiquei).

O recurso é fechado automaticamente pela JVM, portanto, não precisamos fazer isso sozinhos.

Teste

public class Pcg125661 {
  interface F {
    B f(String f);
  }
  interface B {
    void b(int b) throws java.io.IOException;
  }
  public static void main(String[] args) throws java.io.IOException {
    F a = f->b->new java.io.RandomAccessFile(f,"rw").setLength(b);
    a.f("a").b(100);
  }
}

1

AHK, 48 bytes

FileGetSize,s,%1%
2-=s
Loop,%2%
FileAppend,0,%1%

1e 2são os dois primeiros parâmetros em um script AHK.
FileGetSizefunciona em bytes por padrão.
Não é emocionante, mas é simples: obtenha o tamanho, subtraia-o do tamanho desejado e adicione muitos zeros.


1

Perl 6 , 40 bytes

{$_=$^a.IO;.open(:a).put("\0"x($^b-.s))}

$^ae $^bsão os parâmetros para a função - o nome do arquivo e o comprimento, respectivamente.


1

Python 2 , 68 bytes

def g(f,b):
 with open(f,'r+')as c:c.write('\x00'*(b-len(c.read())))

Experimente online! (Ao imprimir o conteúdo do arquivo, o código substitui bytes nulos por 0 ASCII para visibilidade.)


1
Acho que este escreve zeros ASCII e bytes não nulos
— Pavel

Ah ... a palavra zeros era enganosa ...
— totallyhuman

Bem, diz em letras grandes no próprio desafio.
— Pavel

Você pode usar um literal \ x00 na string (não uma sequência de escape)?
— CalculatorFeline

2
Você não pode usar um byte nulo literal, mas \0é mais curto.
— xnor

1

PowerShell, 69 bytes

param($f,$s)@(gc $f -en by)+,[byte]0*($s-(gi $f).length)|sc $f -en by
#     ^ filename
#        ^desired size
#                 ^ get content as byte stream
#           ^force it to an array even if there's 0 or 1 byte
#                          ^append a byte array of nulls..
#                                       ^..desired size - file size
#                            write to file with -encoding byte ^

$fpara o arquivo, $spara o tamanho de destino, salve como .ps1 e execute

.\Add-NullBytesToFile.ps1 .\test.txt 10

É um shell, então deve haver um loop muito pequeno adicionando 1 byte com >>redirecionamento de saída e anexado, certo? Bem, não, porque >>apenas gera codificação UCS2-LE multibyte, portanto não há como adicionar um único byte a um arquivo .. a menos que você esteja usando o PSv5.1 e possa mudar isso, mas isso leva muito tempo para ser competitivo :

$PSDefaultParameterValues['Out-File:Encoding']='utf8';while((gi $f).length-lt$c){[byte]0>>$f}

Talvez exista uma abordagem do .Net Framework? Deveria haver, mas não posso fazê-lo realmente escrever bytes ou erro. Mas é mais longo de qualquer maneira:

param($f,$s)[io.file]::WriteAllBytes($f,[byte[]](,0)*($c-(gi $f).length), $True)

1

Mathematica 50 Bytes

Importação / Exportação

Export[#,Import[#,c="Byte"]~Join~Table[0,{#2}],c]&

Uso

%["test1", 5]

1

q, 29 bytes

Função que leva o nome do arquivo no formato :/foo/bar.baze comprimento como um número inteiro.

{hopen[x](0|y-hcount x)#0x00}

Exemplo:

{hopen[x](0|y-hcount x)#0x00}[`:test.txt;100]

1

C, 56 bytes

fseek(f,0,2);int i;for(;ftell(f)<b;)putc(0,f);fclose(f);

O programa encontra o tamanho do arquivo e quantos bytes anexar. O arquivo adiciona fs - bbytes extras ao final.


1
Welcom para PPCG! Este é um código de golfe desafio do , portanto, seu objetivo é tornar o seu programa o menor possível. Você deve começar removendo espaços em branco desnecessários.
— Pavel

4
Além disso, seu programa parece assumir que as entradas já estão armazenadas nos valores fe b, o que não é permitido. Você deve incluir a E / S em seu programa, que pode ser de ARGV, entrada do console ou argumentos para uma função.
— Pavel

Obrigado, pensei que as variáveis ​​já foram assumidas como definidas. Foi mal.
— Garhoogin

1

C #, 90 bytes

using System.IO;s=>n=>File.AppendAllText(s,new string('\0',(int)new FileInfo(s).Length-n))
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.