设计到算数的问题,求解答

有这样一段java代码

    public static void main(String[] args) {
        int state = 8688201;
        int index = 101;
        for (int i = 1; i < 11; i++) {
            int a1 = state & ((int) Math.pow(8, ((index * 10 + i - 1) % 10)) * 7);
            int a2 = (int) Math.pow(8, ((index * 10 + i - 1) % 10));
            int stateDecode = a1 / a2;
            System.out.println("index:" + (index * 10 + i) + ",stateDecode:" + stateDecode);
        }

    }

可以得到1011到1020的stateDecode,运行结果:

index:1011,stateDecode:1
index:1012,stateDecode:1
index:1013,stateDecode:1
index:1014,stateDecode:1
index:1015,stateDecode:1
index:1016,stateDecode:1
index:1017,stateDecode:1
index:1018,stateDecode:4
index:1019,stateDecode:0
index:1020,stateDecode:0

反之,要是已知1011到1020的stateDecode,如何得到state?

你好 可以得到答案了 有啥看不懂的问

img

package Answer7731784;

import java.util.Arrays;
import java.util.HashMap;

public class Answeer7731784 {
    public static void main(String[] args) {
        int state = 8688201;
        int index = 101;
        HashMap<Integer, Integer> hm = new HashMap<>();

        for (int i = 1; i < 11; i++) {
            int a1 = state & ((int) Math.pow(8, ((index * 10 + i - 1) % 10)) * 7);

            int a2 = (int) Math.pow(8, ((index * 10 + i - 1) % 10));
            int stateDecode = a1 / a2;
            System.out.println("index:" + (index * 10 + i) + ",stateDecode:" + stateDecode);
            hm.put((index * 10 + i), stateDecode);

        }
        int getState = getState(index, hm);
        System.out.println("state="+getState);
    }

    private static int getState(int index, HashMap<Integer, Integer> hm) {
        System.out.println("输入原有的10个映射关系");
        System.out.println(hm);
        System.out.println("开始运算:");
        int[] arry = new int[11];
        boolean flag = true;
        int getState = 0;
        while (flag) {
            int count = 1;
            for (int i = 1; i < 11; i++) {
                int stateD = hm.get(index * 10 + i);
                int a2 = (int) Math.pow(8, ((index * 10 + i - 1) % 10));
                int a1 = stateD * a2;
                while (true) {
                    int a = getState & ((int) Math.pow(8, ((index * 10 + i - 1) % 10)) * 7);
                    if (a == a1) {
                        arry[i] = getState;
                        break;
                    }
                    getState++;
                }
            }
            System.out.println(Arrays.toString(arry));
            for (int i = 1; i < 10; i++) {
                if (arry[i] == arry[i + 1]) {
                    count++;
                }
            }
            if(count==10)
                flag=false;
            
        }
        System.out.println("得到结果: ");
        return getState;
    }

}

已知stateDecode和index 同样的for循环,里面的逻辑变成,先获取到a2,再获取到a1,然后算出((int) Math.pow(8, ((index * 10 + i - 1) % 10)) * 7),最后就进行按位与(都是1才是1)的逆运算,这样会得到很多个state,但肯定有8688201

只知道stateDecode无法求state,看看这个行吗

public static void main(String[] args) {
    int state = 8688201;//输入,我不会Java
    int index = 101;
        for (int i = 1; i < 11; i++)
        {
            int a2 = (int)Math.pow(8, ((index * 10 + i - 1) % 10));
            int a1 = a2 * stateDecode;
            state = a2 ^ a1;
            System.out.println("index:" + (index * 10 + i) + ",state:" + state);
        }
    }
}


由于一个state对应多个stateDecode,从理论上这个算法就是不可逆的。
你可以暴力破,看哪些输入能够对应的输出

不好进行逆运算

因为是多对一,不好进行逆运算,除非有关键唯一id,或者用神经网络

不是一对一,gai不了

解决方法
需要确认下题目中什么是已知条件,什么是未知的,

因为,你题目中已经给了由stateindex获取stateDecode的函数算法,

如果这个题目中的这个函数也是已知的,那么直接尝试根据这个函数逆推一个反向的函数算法看下是否可以得到正确结果。

也就是你的题目需求:stateDecodeindex逆推state


如有问题及时沟通

int a1 = state & ((int) Math.pow(8, ((index * 10 + i - 1) % 10)) * 7);
int a2 = (int) Math.pow(8, ((index * 10 + i - 1) % 10));
int stateDecode = a1 / a2;

先来看看这些数之间的关系,如果已知index、i、stateDecode ,那么可以很简单的求出a1,a2的值。
不妨假设state中的某一位的值为X,((int) Math.pow(8, ((index * 10 + i - 1) % 10)) * 7)中对应的位为A,a1中对应的位为B,其中A、B为已知,求X
即X & A = B ,与运算规则0&0=0,0&1=0,1&0=0,1&1=1,可以很简单的得出如下结论:
当B = 1时,直接可以知道A = X = 1;
当B = 0时,只有在A等于1时,可以知道X = 0;
总结:当A等于1时,可以立即知道X的值且X = B
再来看看((int) Math.pow(8, ((index * 10 + i - 1) % 10)) * 7)这个式子,第一个数0111,第二个数0011 1000....,每个数都有三位为1,都在不同位上,且都是由上一个数向左平移3位得到,那么在样本足够的情况下,是可以知道state中的大部分位的值的,这个式子((int) Math.pow(8, ((index * 10 + i - 1) % 10)) * 7)最大为0011 1000 000000000000000000000000,可以看出最高两位是0,最多可知30位的值,无论state的第30和第31位取何值(从右开始是第0位),都是可行的,因此,要求出唯一的state需要有明确的范围,比如小于这个数,那么是可行的。至于算法,也就出来了。

    public static void main(String[] args) {
        int state = 8688201;
        int index = 101;
        Map<Integer, Integer> cache = new HashMap<>();
        for (int i = 1; i < 11; i++) {
            int a1 = state & ((int) Math.pow(8, ((index * 10 + i - 1) % 10)) * 7);
            int a2 = (int) Math.pow(8, ((index * 10 + i - 1) % 10));
            int stateDecode = a1 / a2;
            System.out.println("index:" + (index * 10 + i) + ",stateDecode:" + stateDecode);
            cache.put(i, stateDecode);
        }
        // {0=1, 1=0, 2=0, 3=1, 4=0, 5=0, 6=1, 7=0, 
        //  8=0, 9=1, 10=0, 11=0, 12=1, 13=0, 14=0, 15=1, 
        //  16=0, 17=0, 18=1, 19=0, 20=0, 21=0, 22=0, 23=1, 
        //  24=0, 25=0, 26=0, 27=0, 28=0, 29=0}
        // 在int范围内 即 XY00 0000 1000 0100 1001 0010 0100 1001
        // XY任意取值都为一个解
        Map<Integer, Integer> result = getState(cache, index);
        System.out.println("可知位:");
        System.out.println(result);
        // 这里因为正好是满足求出了0-29位,可以直接得出一个结果8688201
        int res = 0, idx = 0;
        for (Integer value : result.values()) {
            res = res | (value << (idx++));
        }
        System.out.println("其中的一个结果:");
        System.out.println(res);
    }

    public static Map<Integer, Integer> getState(Map<Integer, Integer> map, int index) {
        Map<Integer, Integer> res = new HashMap<>();
        map.forEach((i, stateDecode) -> {
            int a2 = (int) Math.pow(8, ((index * 10 + i - 1) % 10));
            int a1 = stateDecode * a2;
            int mask = ((int) Math.pow(8, ((index * 10 + i - 1) % 10)) * 7);
            int k = -1;
            while (mask != 0) {
                k ++;
                int A = mask & 1;
                mask = mask >> 1;
                if (A == 0) continue;
                int B = getBit(a1, k);
                res.put(k, B);
            }
        });
        return res;
    }

    public static int getBit(int val, int idx) {
        return (val >> idx) & 1;
    }

只知道stateDecode应该不行,至少同时知道index,然后根据main方法中的算法,逆向反推,先就散出a2,再计算a1,最后计算state

蹲个正确答案

https://blog.csdn.net/lbb1011/article/details/119615147 看这个

这个就像编码器,你写了encode,decode当然也得提供才行