让ChatGPT来写代码和单元测试用例

文章讲述了如何使用SHA-3算法在Java中创建一个类,用于生成和验证HTTP请求的散列,同时对比了GPT-4和文心一言3.5在实现上的差异,强调了文心一言3.5的免费和更全面的边界条件验证。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

写代码的能力上看,文心一言3.5的能力已经很强了,能够和GPT-4各有千秋。

我这里只贴出了GPT-4的实现,文心一言3.5的代码实现也是类似的,只是会提示JDK没有实现SHA-3-256,需要引入第三方库。但是生成的单元测试用例明显好于GPT-4,对于边界条件验证的更加充分。足够用了,关键文心一言3.5还免费。

业务功能:

对于任意HTTP请求,都可以基于URI和请求参数/参数值对请求进行散列,计算出http请求的散列字符串值sign来。

服务端强制要求每一个HTTP请求都必须包含sign参数和值。

确保不知道prefix具体值的任何用户都无法构造出一个有效HTTP请求。

  提示词:

请写一个Java类,利用SHA-3算法来对http的GET/POST请求URI和参数以及参数值进行散列和校验。

1)静态的常量字符串  prefix,由随机字符构成的字符串,长度为32个字符。

方法1)求HTTP请求URI和参数、参数值的生成SHA-3散列字符串值
输入参数: 
参数1,名称为 httpURI,类型为String,是HTTP请求的URI的字符串;
参数2,名称为 parameters,类型是HashMap<String,String>,其中key为HTTP请求的参数,value为参数对应的字符串值;

返回值:
返回值为String,为httpURI和参数parameters使用SHA-3算法来散列后的字符串值,用sign来表示。

方法要求:
待散列的字符串 : httpURI?key1=value1&key2=value2&key3=value3&prefix
其中key1/key2/key3是严格按照参数名称的ASCII码升序排列后的参数名称;
其中value1/value2/value3是对应的参数key1/key2/key3的值,参数值需要采用URL编码;
其中prefix表示一个加盐字符串,prefix的内容不会出现在用户的HTTP请求中,而是服务端写死的字符串值;

方法2)根据HTTP请求的URI和参数、参数值以及本次请求的散列码来判定请求是否合法
输入参数: 
参数1,名称为 httpURI,类型为String,是HTTP请求的URI的字符串;
参数2,名称为 parameters,类型是HashMap<String,String>,其中key为HTTP请求的参数,value为参数对应的字符串值;

返回值:
返回值为boolean,表示对于HTTP请求的URI和参数名称/参数值的SHA-3校验是否通过,通过则返回true。

方法要求:
参数2中必须要包含 一个参数 sign,该参数值不能为空,为空则校验不通过。
把方法2的参数用方法1来计算一个SHA-3的散列值,注意参数sign和sign的值不能参加散列。
用计算出来的散列字符串和HTTP请求中的sign参数的值进行比较,两个字符串值完全一致则认为校验结果为true,反之为false。

GPT-4生成的代码如下:

import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;
import java.net.URLEncoder;

public class HttpSignatureValidator {
    // 静态常量字符串prefix,由随机字符构成的字符串,长度为32个字符
    private static final String PREFIX = "abcdefghijklmnopqrstuvwxyz123456"; // 示例

    // 方法1: 生成SHA-3散列字符串值
    public static String generateSignature(String httpURI, HashMap<String, String> parameters) throws NoSuchAlgorithmException {
        // 按ASCII码升序排列参数,并进行URL编码
        String sortedParameters = parameters.entrySet().stream()
            .sorted(Map.Entry.comparingByKey())
            .map(entry -> entry.getKey() + "=" + urlEncode(entry.getValue()))
            .collect(Collectors.joining("&"));

        // 待散列的字符串
        String toHash = httpURI + "?" + sortedParameters + "&" + PREFIX;
        return hashSHA3(toHash);
    }

    // 方法2: 根据HTTP请求的URI和参数、参数值以及本次请求的散列码判断请求是否合法
    public static boolean validateRequest(String httpURI, HashMap<String, String> parameters) throws NoSuchAlgorithmException {
        String providedSignature = parameters.get("sign");
        // 如果sign为空或不存在,则校验不通过
        if (providedSignature == null || providedSignature.isEmpty()) {
            return false;
        }

        // 从参数中移除sign后进行散列
        parameters.remove("sign");
        String calculatedSignature = generateSignature(httpURI, parameters);
        return providedSignature.equals(calculatedSignature);
    }

    // 对字符串进行URL编码
    private static String urlEncode(String value) {
        try {
            return URLEncoder.encode(value, StandardCharsets.UTF_8.toString());
        } catch (Exception e) {
            return ""; // 简化处理
        }
    }

    // 使用SHA-3算法进行散列
    private static String hashSHA3(String data) throws NoSuchAlgorithmException {
        MessageDigest digest = MessageDigest.getInstance("SHA3-256");
        byte[] hash = digest.digest(data.getBytes(StandardCharsets.UTF_8));
        return bytesToHex(hash);
    }

    // 字节数组转为十六进制字符串
    private static String bytesToHex(byte[] bytes) {
        StringBuilder hexString = new StringBuilder();
        for (byte aByte : bytes) {
            String hex = Integer.toHexString(0xff & aByte);
            if (hex.length() == 1) hexString.append('0');
            hexString.append(hex);
        }
        return hexString.toString();
    }

    // 测试方法
    public static void main(String[] args) throws Exception {
        HashMap<String, String> parameters = new HashMap<>();
        parameters.put("key1", "value1");
        parameters.put("key2", "value2");
        parameters.put("key3", "value3");

        String httpURI = "/api/test";
        String signature = generateSignature(httpURI, parameters);
        System.out.println("Signature: " + signature);

        parameters.put("sign", signature);
        boolean isValid = validateRequest(httpURI, parameters);
        System.out.println("Request is valid: " + isValid);
    }
}

复制代码在JAVA环境下直接可用。

接下来让GPT-4来生成单元测试代码。

提示词:

给上述JAVA类和方法生成单元测试用例,注意边界用例不能遗漏,保证测试通过后的代码能够在健壮、正确,直接生产环境可用。

GPT-4生成的单元测试代码:

import static org.junit.Assert.*;
import org.junit.Test;
import java.util.HashMap;

public class HttpSignatureValidatorTest {
    // 测试正常情况下的散列和验证
    @Test
    public void testValidSignatureAndValidation() throws Exception {
        String httpURI = "/api/test";
        HashMap<String, String> parameters = new HashMap<>();
        parameters.put("key1", "value1");
        parameters.put("key2", "value2");
        parameters.put("key3", "value3");

        String signature = HttpSignatureValidator.generateSignature(httpURI, parameters);
        assertNotNull(signature);

        parameters.put("sign", signature);
        assertTrue(HttpSignatureValidator.validateRequest(httpURI, parameters));
    }

    // 测试参数为空的情况
    @Test
    public void testEmptyParameters() throws Exception {
        String httpURI = "/api/test";
        HashMap<String, String> parameters = new HashMap<>();

        String signature = HttpSignatureValidator.generateSignature(httpURI, parameters);
        assertNotNull(signature);

        parameters.put("sign", signature);
        assertTrue(HttpSignatureValidator.validateRequest(httpURI, parameters));
    }

    // 测试参数值包含特殊字符
    @Test
    public void testParametersWithSpecialChars() throws Exception {
        String httpURI = "/api/test";
        HashMap<String, String> parameters = new HashMap<>();
        parameters.put("key1", "value 1&value=2");

        String signature = HttpSignatureValidator.generateSignature(httpURI, parameters);
        assertNotNull(signature);

        parameters.put("sign", signature);
        assertTrue(HttpSignatureValidator.validateRequest(httpURI, parameters));
    }

    // 测试sign参数不存在的情况
    @Test
    public void testNoSignParameter() throws Exception {
        String httpURI = "/api/test";
        HashMap<String, String> parameters = new HashMap<>();
        parameters.put("key1", "value1");

        assertFalse(HttpSignatureValidator.validateRequest(httpURI, parameters));
    }

    // 测试使用错误的sign值进行验证
    @Test
    public void testInvalidSign() throws Exception {
        String httpURI = "/api/test";
        HashMap<String, String> parameters = new HashMap<>();
        parameters.put("key1", "value1");
        parameters.put("sign", "invalid");

        assertFalse(HttpSignatureValidator.validateRequest(httpURI, parameters));
    }
}

单元测试代码是直接可用的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值