Solo pares de bytes

64

El escenario

Últimamente has notado un comportamiento extraño con tu editor de texto favorito. Al principio parecía que estaba ignorando caracteres aleatorios en su código al escribir en el disco. Después de un tiempo notó un patrón; Se ignoraron los caracteres con valores ASCII impares. Bajo una inspección adicional descubrió que solo puede escribir en archivos correctamente si cada octavo bit es cero. Ahora necesita saber si sus archivos valiosos se han visto afectados por este extraño error.

La tarea

Debe escribir un programa completo que determine si un archivo contiene bytes impares (lo que demuestra que no está dañado). Pero debido a su editor de texto, no puede escribir bytes impares en su código fuente. Puede asumir cualquier codificación preexistente para la entrada, sin embargo, aún debe verificar cada byte individual, no solo los caracteres.

Entrada

Su programa tomará el contenido o la ruta a un archivo desde stdin o línea de comando.

Salida

Su programa generará en stdout un valor verdadero si el archivo dado contiene un byte impar o falso si cada octavo bit es cero.

Criterios

Este es el código de golf, el programa más corto que completa la tarea gana. Para ser un envío válido cada octavo bit en el código fuente de los archivos debe ser un cero. Recomendaría incluir una copia de los binarios de su código fuente en su envío.

Se aplican lagunas estándar .

Casos de prueba

(En codificación ASCII) Entrada:

"$&(*,.02468:<>@BDFHJLNPRTVXZ\^`bdfhjlnprtvxz|~

Output:
falsy

Input:
!#%')+-/13579;=?ACEGIKMOQSUWY[]_acegikmoqsuwy{}

Output:
truthy

Input:
LOREMIPSVMDOLORSITAMETCONSECTETVRADIPISCINGELITSEDDOEIVSMODTEMPORINCIDIDVNTVTLABOREETDOLOREMAGNAALIQVA
VTENIMADMINIMVENIAMQVISNOSTRVDEXERCITATIONVLLAMCOLABORISNISIVTALIQVIPEXEACOMMODOCONSEQVAT
DVISAVTEIRVREDOLORINREPREHENDERITINVOLVPTATEVELITESSECILLVMDOLOREEVFVGIATNVLLAPARIATVR
EXCEPTEVRSINTOCCAECATCVPIDATATNONPROIDENTSVNTINCVLPAQVIOFFICIADESERVNTMOLLITANIMIDESTLABORVM

Output:
truthy

Consejos

  • Elija el idioma sabiamente, este desafío podría no ser posible en todos los idiomas

  • El comando Unix xxd -b <file name>imprimirá los binarios de un archivo en la consola (junto con algunas cosas de formato adicionales)

  • Puede usar otras codificaciones que no sean ASCII, como UTF-8, siempre que se sigan todas las demás reglas

Asistente de trigo
fuente
2
Algunos idiomas tienen dificultades para leer entradas de varias líneas, pero no es que este desafío sea fácil, por lo que probablemente esté bien. : P ¿Puede la entrada estar vacía?
Dennis
99
!#%')+-/13579;=?ACEGIKMOQSUWY[]_acegikmoqsuwy{}son los caracteres ASCII imprimibles prohibidos, para cualquier persona que se preocupe. Los caracteres ASCII imprimibles permitidos son" $&(*,.02468:<>@BDFHJLNPRTVXZ\^`bdfhjlnprtvxz|~
Patrick Roberts el
99
Muy útil que todas las vocales estén prohibidas ... ;-)
owacoder
44
Bien, mucho para que BF tenga una oportunidad en este desafío.
TLW
2
También tenga en cuenta que si tiene saltos de línea en un archivo DOS / Windows, [CR]tiene un bit extraño. Esperaba que WhiteSpace estuviera a salvo, pero desgraciadamente [TAB]. Si quieres ir a la vieja escuela, EBCDIC te da tres vocales.
GuitarPicker

Respuestas:

26

GS2 , 4 bytes

dΦ("

Pruébalo en línea!

Hexdump

0000000: 64 e8 28 22                                      d.("

Cómo funciona

      (implicit) Read all input and push it on the stack.
 Φ    Map the previous token over all characters in the string:
d       Even; push 1 for even characters, 0 for odd ones.
  (   Take the minimum of the resulting list of Booleans.
   "  Negate the minimum.
Dennis
fuente
21

Befunge, 36 bytes

Sé que esta es una vieja pregunta, pero quería intentarlo porque pensé que sería un desafío interesante en Befunge.

>~:0`|
>20`:>$.@
|` " "<
*8*82<^p24*

Pruébalo en línea!

Sale 1si la entrada está dañada (es decir, contiene un byte impar) y 0si está bien.

Explicación

El problema es cómo determinar bytes impares sin tener acceso a los comandos /(dividir) o %(módulo). La solución fue multiplicar el valor por 128 (la secuencia 28*8**), luego escribir ese resultado en el campo de juego. En un intérprete estrictamente estándar, las celdas del campo de juego son valores de 8 bits con signo, por lo que un número impar multiplicado por 128 se trunca a -1 mientras que un número par se convierte en 0.

El otro truco fue leer el -1 o 0 desde el campo de juego sin tener acceso al gcomando (get). La solución para esto era escribir el valor en el medio de una secuencia de cadena existente ( " "), luego ejecutar esa secuencia para empujar el valor encerrado en la pila. En ese punto, determinar la rareza del byte es una simple prueba de menos de cero.

Un aspecto final que vale la pena discutir es el resultado. En el caso falso, alcanzamos la >$.secuencia con solo un valor en la pila, por lo que $borra la pila haciendo que la .salida sea cero. En el caso verdadero, seguimos el camino 20`:>$.. Como dos es mayor que cero, la comparación empuja un uno a la pila, y :hace una copia duplicada para $que no se caiga antes de que salga.

James Holderness
fuente
1
Esto puede ser tarde y nuevo, pero ya es mi respuesta favorita.
Wheat Wizard
@WheatWizard Acabo de darme cuenta ahora por qué esta respuesta ha recibido tanta atención. Gracias por la generosidad!
James Holderness
12

CJam (11 bytes)

"r2":(~f&2b

Demostración en línea

Eliminando los trucos para evitar bytes impares, esto se reduce a

q1f&2b

que lee la entrada, asigna un AND bit a bit 1y luego realiza una conversión de base, dando cero si todos los AND fueran cero.

Peter Taylor
fuente
3
Este código es triste:(
betseg
Porque solo puede tener la mitad de los caracteres @betseg
Roman Gräf
9

Archivo .COM imprimible, 100 bytes

^FZjfDXVL\,LPXD$$4"PXD,lHPXDjJXDRDX@PXDjtXDH,nPXDj@XD4`@PXD,ZHPXD4,@PXD4:4"PXDH,\PXD4"PXD,hPXDRDX@P\

Hexdump:

00000000  5e 46 5a 6a 66 44 58 56  4c 5c 2c 4c 50 58 44 24  |^FZjfDXVL\,LPXD$|
00000010  24 34 22 50 58 44 2c 6c  48 50 58 44 6a 4a 58 44  |$4"PXD,lHPXDjJXD|
00000020  52 44 58 40 50 58 44 6a  74 58 44 48 2c 6e 50 58  |RDX@PXDjtXDH,nPX|
00000030  44 6a 40 58 44 34 60 40  50 58 44 2c 5a 48 50 58  |Dj@XD4`@PXD,ZHPX|
00000040  44 34 2c 40 50 58 44 34  3a 34 22 50 58 44 48 2c  |D4,@PXD4:4"PXDH,|
00000050  5c 50 58 44 34 22 50 58  44 2c 68 50 58 44 52 44  |\PXD4"PXD,hPXDRD|
00000060  58 40 50 5c                                       |X@P\|
00000064

Usando una definición muy flexible de la fuente como algo que puede ser escrito razonablemente por un humano e inspirado en el archivo de prueba de antivirus estándar EICAR (más información en "Diviértase con el archivo de prueba EICAR" en Bugtraq).

Usando solo bytes ASCII no impares imprimibles (nota al margen: los códigos de operación que afectan a las palabras tienden a ser extraños, el bit W es el lsb de algunos códigos de operación), construye un fragmento de código en SP (que convenientemente establecemos justo después de nuestro código de generación) , y la ejecución termina cayendo al código generado.

Utiliza el hecho de que la pila inicialmente contiene un puntero cercano al inicio de la PSP, y que el inicio de la PSP contiene la INT 20hinstrucción (más información sobre esto en https://stackoverflow.com/questions/12591673/ ).

Fuente real:

; we want to generate the following fragment of code

;  5E                pop si             ; zero SI (pop near pointer to start of PSP)
;  46                inc si             ; set SI to 1
; loop:
;  B406              mov ah,0x6         ; \
;  99                cwd                ; >
;  4A                dec dx             ; > D-2106--DLFF
;  CD21              int 0x21           ; > DIRECT CONSOLE INPUT
;  7405              jz end             ; > jump if no more input
;  40                inc ax             ; > lsb 0/1 odd/even
;  21C6              and si,ax          ; > zero SI on first odd byte
;  EBF3              jmp short loop     ; /
; end:
;  96                xchg ax,si         ; return code
;  B44C              mov ah,0x4c        ; D-214C
;  CD21              int 0x21           ; TERMINATE WITH RETURN CODE

 pop si             ; this two opcodes don't need to be encoded
 inc si

 pop dx             ; DX = 20CD (int 0x20 at start of PSP)
 push byte +0x66
 inc sp
 pop ax
 push si
 dec sp
 pop sp             ; SP = 0x0166
 sub al,0x4c        ; B4
 push ax
 pop ax
 inc sp
 and al,0x24
 xor al,0x22        ; 06
 push ax
 pop ax
 inc sp
 sub al,0x6c
 dec ax             ; 99
 push ax
 pop ax
 inc sp
 push byte +0x4a    ; 4A
 pop ax
 inc sp
 push dx            ; [20]CD
 inc sp
 pop ax
 inc ax             ; 21
 push ax
 pop ax
 inc sp
 push byte +0x74    ; 74
 pop ax
 inc sp
 dec ax
 sub al,0x6e        ; 05
 push ax
 pop ax
 inc sp
 push byte +0x40    ; 40
 pop ax
 inc sp
 xor al,0x60
 inc ax             ; 21
 push ax
 pop ax
 inc sp
 sub al,0x5a
 dec ax             ; C6
 push ax
 pop ax
 inc sp
 xor al,0x2c
 inc ax             ; EB
 push ax
 pop ax
 inc sp
 xor al,0x3a
 xor al,0x22        ; F3
 push ax
 pop ax
 inc sp
 dec ax
 sub al,0x5c        ; 96
 push ax
 pop ax
 inc sp
 xor al,0x22        ; B4
 push ax
 pop ax
 inc sp
 sub al,0x68        ; 4C
 push ax
 pop ax
 inc sp
 push dx            ; [20]CD
 inc sp
 pop ax
 inc ax
 push ax            ; 21
 pop sp             ; now get the stack out of the way
ninjalj
fuente
9

MATL , 7 bytes

l$Z$2\z

El código fuente usa codificación UTF-8. Entonces los bytes de origen son (en decimal)

108    36    90    36    50    92   122

La entrada es un nombre de archivo, tomado como una cadena entre comillas simples. La salida es el número de bytes impares en el archivo, lo cual es cierto si no es cero.

Explicación

l    % Push a 1. We use `l` instead of `1` to have an even value
$    % Input specificication. This indicates that the next function takes 1 input
Z$   % Input file name implicitly, read its raw bytes and push them as an array of chars
2\   % Modulo 2
z    % Number of nonzero values. This gives the number of odd bytes. Implicitly display
Luis Mendo
fuente
8

CJam, 18 17 15 bytes

"<rj":(((*~:|X&

Asume que la configuración regional está establecida en Latin-1. Pruébalo en línea!

Cómo funciona

La solución directa es la siguiente.

q       e# Read all input from STDIN and push it as a string on the stack.
 :i     e# Cast each character to its code point.
   :|   e# Take the bitwise OR of all code points.
     X  e# Push 1.
      & e# Take the bitwise AND of the logical OR and 1.

Lamentablemente, los caracteres qy ino pueden aparecer en el código fuente. Para solucionar este problema, crearemos dinámicamente parte del código fuente anterior y luego evaluaremos la cadena.

"<rj"         e# Push that string on the stack.
     :(       e# Decrement all characters, pushing ";qi".
       (      e# Shift out the first character, pushing "qi" and ';'.
        (     e# Decrement ';' to push ':'.
         *    e# Join "qi" with separator ':', pushing "q:i". 
          ~   e# Evaluate the string "q:i", which behaves as explained before.
Dennis
fuente
7

Pyth, 20 13 bytes

vj0>LhZ.BRj.z

O en binario:

00000000: 01110110 01101010 00110000 00111110 01001100 01101000  vj0>Lh
00000006: 01011010 00101110 01000010 01010010 01101010 00101110  Z.BRj.
0000000c: 01111010                                               z

Pruébalo en línea

Cómo funciona

           .z   all lines of input
          j     join on newline
       .BR      convert each character to binary
   >LhZ         take the last (0 + 1) characters of each binary string
 j0             join on 0
v               evaluate as an integer

El entero resultante es verdadero (distinto de cero) si alguno de los bytes fuera impar.

Anders Kaseorg
fuente
4

Jalea , 13 bytes

24‘ịØBvF|\ṪBṪ

Espera la entrada como un argumento de línea de comandos entre comillas. Pruébalo en línea!

Hexdump

0000000: 32 34 fc d8 12 42 76 46 7c 5c ce 42 ce           24...BvF|\.B.
Dennis
fuente
Si no fuera por la restricción de bytes impar, esto sería igual de trabajar a los 6 bytes: O%2¬Ạ¬.
Erik the Outgolfer
4

Retina , 106 bytes

Elimina todos los caracteres permitidos, luego coincide con los caracteres restantes. Los valores de verdad serán la cantidad de caracteres encontrados. Los valores de Falsey serán 0.

`"| |\$|&|\(|\*|,|\.|0|2|4|6|8|:|<|>|@|B|D|F|H|J|L|N|P|R|T|V|X|Z|\\|\^|`|b|d|f|h|j|l|n|p|r|t|v|x|z|\||~

.

Pruébalo en línea

Como .no coincide con las nuevas líneas de forma predeterminada, no tengo que eliminarlas.

mbomb007
fuente
1

Perl 5 + -p0, 136 bytes

Similar a otras respuestas, esto elimina todos los bytes pares y deja los bytes impares (lo cual es cierto).

tr<�
 "$&(*,.02468:<>@BDFHJLNPRTVXZ\\^`bdfhjlnprtvxz|~€‚„†ˆŠŒŽ’”–˜šœž ¢¤¦¨ª¬®°²´¶¸º¼¾ÀÂÄÆÈÊÌÎÐÒÔÖØÚÜÞàâäæèêìîðòôöøúüþ><>d

Pruébalo en línea!

Dom Hastings
fuente
-0no hace nada a las nuevas líneas. Solo determina cómo dividir la entrada, no elimina ningún carácter.
Ørjan Johansen
Ay eso es muy malo.
Ørjan Johansen
@ ØrjanJohansen Sí, tienes razón -0, quería hacer todo el bloque como un bulto, pero eso no debería importar, pero no puedo evitar esto ... ¡Lástima! Limpiaré estos comentarios. Gracias por el aviso!
Dom Hastings
¿Entonces funciona ahora? Supongo que debería eliminar algunos de los comentarios. Desde el diferencial de edición, veo que ahora estás incluyendo cada byte par en el programa. Creo que es posible que desee decir eso explícitamente, ya que no todos esos personajes aparecen (al menos para mí).
Ørjan Johansen
@ ØrjanJohansen sí! Creo que lo tengo ahora. No creo que todas las otras respuestas cubran todos los bytes pares tampoco, creo que algunas solo funcionan en ASCII imprimible. Estoy bastante seguro de que esto hace lo que quería ahora. ¡De cualquier modo eso espero!
Dom Hastings
0

Japt , 10 bytes

ø0ôH² ®dZÄ

Pruébalo en línea!

La página de códigos de Japt es ISO-8859-1. El código da falsecuando se ingresa como una cadena, por lo tanto, un envío válido.

Desempaquetado y cómo funciona

Uø0ôHp2  mZ{ZdZ+1

Uø      Does input string contain any element in the following array...?
0ôHp2     Range of 0 to 32**2, inclusive
mZ{       Map...
ZdZ+1       Convert the number Z to a char having charcode 2*Z+1

No tener String.c(obtener charcode o mapear sobre códigos de char) fue un dolor, pero afortunadamente lo hay Number.d(convertir número a char).

Resulta que Japt gana a CJam, Pyth y Jelly :)


Sin la restricción, hay un par de formas de hacerlo en 6 bytes (a la par con CJam y Jelly nuevamente):

®c uÃn

Unpacked: UmZ{Zc u} n

UmZ{   Map on each char...
Zc u     Convert to charcode modulo 2
}
n      Convert the resulting string to number

"000..000"se convierte al número 0 (falso) independientemente de cuánto tiempo sea. Por otro lado, cualquier cosa que contenga 1 se convierte en un valor distinto de cero double, o Infinitysi es demasiado grande (ambos de verdad).

¬d_c u

Unpacked: q dZ{Zc u

q    Convert to array of chars
dZ{  Is something true when mapped with...
Zc u   Convert each char to charcode modulo 2

Enfoque más directo que rinde directamente trueo false.

O incluso, la solución de 5 bytes es posible con la ayuda de -dflag:

¨c u

Unpacked: q mZ{Zc u

q     Convert to array of chars
mZ{   Map...
Zc u    Convert to charcode modulo 2

      Result is array of zeros and ones
-d    Apply .some() on the resulting array
Bubbler
fuente