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
Pavel
fonte
@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 .

Trauma Digital
fonte
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.
Urna de polvo mágico
fonte
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)
Cajado
fonte
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");
Titus
fonte
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);
  }
}
Olivier Grégoire
fonte
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.

Engenheiro Toast
fonte
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.

Sean
fonte
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.)

totalmente humano
fonte
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)
TessellatingHeckler
fonte
1

Mathematica 50 Bytes

Importação / Exportação

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

Uso

%["test1", 5]
Kelly Lowder
fonte
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]
skeevey
fonte
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.

Garhoogin
fonte
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))
TheLethalCoder
fonte