Si conozco el resultado de una función (programación), ¿es posible obtener una lista de posibles entradas?

Mi consejo es general y no necesariamente se aplicará a JavaScript.

Dada una función y solo su salida, puede ser increíblemente difícil descubrir qué entrada la causó, especialmente para una salida inesperada.

Si comprende el entorno operativo y tiene acceso privilegiado, a veces puede examinar la memoria en la pila de llamadas (en binario) después de una llamada a la función. Para valores no sobrescritos, puede ver lo que estaban en la llamada de función, posiblemente revelando todos los parámetros.

De manera más realista, suponga que solo tiene una tabla de resultados y desea saber qué entrada los produjo. Las dificultades incluyen:

  • Mapeo de muchos a uno . Una sola salida puede ser el resultado de muchas entradas diferentes. Por ejemplo, si la función es SquareOf (x) y la salida es 9, ¿cómo saber si era una entrada +3 o -3 para x? Ambos resultan en 9.
  • Cambio en no parámetros . Tal vez la función utiliza variables externas que tienen valores diferentes en diferentes momentos. Tal vez está usando una variable no inicializada cuyo valor depende de lo que sucedió antes de esta llamada. Tal vez hay una función incluida en función de la hora actual, la dirección IP, quién sabe qué. A menos que conozca estos valores que no son parámetros a priori, no puede controlarlos ni identificarlos.
  • Comportamiento inesperado No solo está tratando de encontrar las entradas que producen un resultado esperado, sino uno aberrante. Dada nuestra función SquareOf (), imagine si algún valor devuelve ‘-9’. ¿Cómo diablos puedes intuir qué parámetros probar?

Si realmente desea encontrar el problema, le recomiendo las siguientes opciones. Tenga en cuenta que estos se centran en encontrar el problema en lugar de solo encontrar las entradas.

  1. Registro Registre los parámetros de entrada junto con el parámetro de salida, para que no vuelva a tener este problema.
  2. Validación de parámetros . Basura dentro basura fuera. Agregue comprobaciones para asegurarse de que los valores de entrada estén en el rango que espera, por ejemplo, 0… 4,096 para las coordenadas de pantalla x e y.
  3. Memoria comprobada Obtenga una pila de memoria comprobada que controlará estrictamente el acceso a la memoria y ejecute su función en ella. Si se accede a una ubicación de memoria o variable de manera inesperada, arroja una excepción. Alimente una amplia variedad de entradas esperadas para la función y espere una excepción.
  4. Implementación paralela . Escriba una función similar desde cero y genere algún tipo de tabla o secuencia de entradas y salidas esperadas. Luego alimente las entradas de la tabla en las funciones reales y compárelas con la salida. Alternativamente, solo llame a ambas funciones en tiempo de ejecución y compare sus resultados.
  5. Parámetro de barrido exhaustivo . Recorre todas las combinaciones de valores de parámetros de entrada, haciendo una pausa cuando uno genera tu salida. Tenga en cuenta que es posible que la función nunca vuelva a generar esa salida si depende del valor de una variable no inicializada.
  6. Valores aleatorios Intente valores de entrada aleatorios para la función hasta que genere un valor de salida claramente fuera de rango, luego haga una pausa.

Problema difícil Cuando me enfrento a cosas como esta, trato de rastrearlas. Si todavía no puedo encontrarlo, guardo ese fragmento de código, lo reescribo desde cero y veo si el problema desaparece. Por lo general lo hace.

A2A

Hm, bueno … si entiendo eso correctamente, no podrás saber todas las entradas posibles basadas en una salida de funciones como generalmente no sabes, lo que sucede en una función (es decir, el procesamiento de las funciones de los datos). Hay cierta aproximación, pero te quedaría un factor x que sería desconocido.

Pero esto supone una caja negra. Piense en ello como una prueba de caja negra. Pon algo y mira la salida. Lo que sucede dentro no importa, solo prueba la salida esperada.

Como escribió en los detalles aquí, puede ver el código. Entonces tiene la posibilidad de determinar las funciones de procesamiento de datos. Aquí, tengo que preguntar, ¿por qué no puede determinar la entrada de funciones? Debe haber la definición de funciones donde se le pasan los parámetros necesarios. ¿Qué es lo que no puedes encontrar?

En general, si tengo una caja negra con la que estoy trabajando y no hay documentación, simplemente hago un reconocimiento. Lo que significa que arrojo algo, monitorizo ​​la salida y luego deduzco de eso.

por ejemplo: si llamo a la función con un parámetro String y la salida es una excepción, diciendo que solo se permiten enteros, entonces puedo ir un paso más allá y probar mis siguientes parámetros.

O, si es complicado, ya que puede haber alguna manipulación de cadenas, etc., agrego algunas cadenas que siempre reconoceré, como “@@@@ 3333” o “? 12345 ?!”. Entonces podré buscar mis entradas como patrones.

Estos son algunos ejemplos fáciles, ya que, por supuesto, hay situaciones mucho más complejas. Tal vez tenga una salida compilada o encriptada, o haya una especie de enmascaramiento ya que la función inicial está llamando a una docena de otras funciones y funciona con algunos calbacks, etc.

Pero de todos modos, la forma más fácil es siempre un buen punto para comenzar.

No soy experto en JavaScript, pero su problema es adecuado para Fuzzing. Puede probar los fuzzers de Javascript en su función [1] [2] [3]. No pude encontrar ningún fuzzer de JavaScript que genere entradas a partir de la salida dada. También puede realizar pruebas basadas en propiedades [4].

[1] mapbox / fuzzer

[2] NodeGuy / JavaScript-fuzz

[3] lydell / depresión

[4] jsverify / jsverify

¿No puedes modificar ligeramente el código?

Si puedes modificar el código,

Si se trata de un script js que se ejecuta en el navegador , hay una función muy útil llamada alerta . Esto arrojará la salida como un diálogo modal en el navegador.

Si está en el lado del servidor , tendrá que buscar console.log o es equivalente a imprimir el contenido. Similar a printf en C o imprimir en Python .

función (evento) {

console.log (event.memberElement);

}

También puede acceder a los nombres de variables de campo, prototipos y nombres de funciones de un objeto js, ​​si no está seguro del contenido.

Si no puede modificar el código,

En los navegadores , Firefox, Safari, Chrome e IE, tiene herramientas para desarrolladores. Puede depurar el código y recorrerlo. ¡Minified js es una pesadilla de depuración!

En el lado del servidor, puede haber algunas utilidades de depuración como Node.js v8.1.0 Documentation para nodejs. Estoy seguro de que su biblioteca js admite la depuración con algún otro paquete. Siempre puede recurrir a stackoverflow para obtener más ayuda 😉

Este es de hecho un problema divertido y emocionante.

Comience mirando el problema SAT: problema de satisfacción booleana – Wikipedia

(Hace unas semanas tuve que implementar una solución al problema SAT, que a pesar de sus optimizaciones se degrada al peor de los casos O (2 ^ n), ¡no es tan bueno si n crece!)

Entonces, con tiempo y memoria infinitos, puede determinar todas las salidas posibles de una función estable dadas todas las entradas posibles.

Pero no es así como la mayoría de nosotros tratamos de resolver el problema que usted describe. En general, comenzamos al final de la función y trabajamos hacia atrás. En otras palabras, usando el razonamiento, tomamos el resultado de la función y descubrimos cómo podría haber ocurrido dicho resultado. La clave está en esta declaración:

Si tiene acceso a la fuente, intente encontrar todas las invocaciones de esa función. Hubiera pensado que la declaración de función renunciaría a todos los argumentos que necesita. Si ese no es el caso, entonces encontrar todas las invocaciones definitivamente lo hará. Debería poder obtener toda la información que necesita del contexto circundante de esas invocaciones.

Si es una función pura (su salida depende solo de los parámetros de entrada) puede ser posible. Pero incluso entonces, no siempre, o incluso a menudo.

Considerar

int sum (int a, int b) => a + b

Su salida es 9.

Hay MUCHOS valores posibles para la entrada. Entonces depende de la función.

Puede agregar el registro a la función para almacenar las entradas y salidas para cada llamada en algún lugar. Ese podría ser un buen diagnóstico.

Quizás deba proporcionar detalles adicionales como:

  1. Función de script Java
  2. Muestras de buenos insumos y resultados esperados.
  3. Ejemplo de salida inesperada

La función de script java debe ser comprobable en una computadora aislada sin el resto del código. Lo que significa que es posible que desee crear un caso de prueba aislado para su función en Crear un nuevo violín y luego hacer su pregunta.

Use argumentos objeto dentro de la función y conocerá la entrada, sea cual sea