JAVA模拟生成新能源汽车数据——随机生成车架号

本文详细介绍了如何使用JAVA模拟生成符合规范的车架号,包括车架号的组成部分、校验码计算、生成随机年份代码、生产序号等,以及如何确保车架号的正确性。此外,还讨论了在生成新能源车辆数据时的注意事项,如数据存储格式、数据量要求、重复数据和历史数据的混合等。

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

 

目录

二.随机生成车架号

        1、车架号的组成部分

 (1)第1位:代表出厂国家/地区

(2)第2位:代表汽车制造商代码

(3)第3位:车系代码 

(4)第4位:排量或安全保护装置

(5)第5位:车身类型

(6)第6位:发动机变速箱

(7)第7-8位:车型代码

(8)第9位:校验码

(9)第10位:出厂年份

(10)第11位:车辆组装地(装配厂)

(11)第12~17位:出厂顺序代码

2、生成车架号可能需要的字符

 3、计算校验码

4、通过判断车架号的第9位是否是正确的校验码,判断车架号vin是否正确

5、生成随机车辆特征

6、生成随机年份代码

7、 生成随机的生产序号

8、拼接车架号

 9、返回随机字符

 10、获取随机车架号

11、获取对应数量的随机车架号

 12、随机获取重复的车架号

三、随机生成车架号代码整理


 

模拟生成新能源车辆数据

编写一个程序,每天凌晨3点模拟生成当天的新能源车辆数据(字段信息必须包含:车架号、行驶总里程、车速、车辆状态、充电状态、剩余电量SOC、SOC低报警、数据生成时间等)。

要求:1、最终部署时,要将这些数据写到第一题的HDFS中。(如果有多个组做第一题,则任选一个HDFS即可);

2、车辆数据要按天存储,数据格式是JSON格式,另外如果数据文件大于100M,则另起一个文件存。每天的数据总量不少于300M。比如假设程序是2023-01-1 03点运行,那么就将当前模拟生成的数据写入到HDFS的/can_data/2023-01-01文件夹的can-2023-01-01.json文件中,写满100M,则继续写到can-2023-01-01.json.2文件中,依次类推;

3、每天模拟生成的车辆数据中,必须至少包含20辆车的数据,即要含有20个车架号(一个车架号表示一辆车,用字符串表示);

4、每天生成的数据中要有少量(20条左右)重复数据(所有字段都相同的两条数据则认为是重复数据),且同一辆车的两条数据的数据生成时间间隔两秒;

5、每天生成的数据中要混有少量前几天的数据(即数据生成时间不是当天,而是前几天的)。

二.随机生成车架号

        1、车架号的组成部分

 (1)第1位:代表出厂国家/地区

地理区域的分配规则如下:1-5为北美,6-7为大洋洲,8、9和0为南美洲,A-H为非洲,J-R为亚洲,S-Z为欧洲。具体如下:

(2)第2位:代表汽车制造商代码

全球常见汽车制造商代码表格如下:

(3)第3位:车系代码 

第4~8位:描述车辆特征

这几位,不同的厂商,字符的解析意思不尽相同。一汽奥迪的如下:

(4)第4位:排量或安全保护装置

A-安全带;B-安全带+安全气囊;2-1.4T;3-2.0T;4-2.4;5-2.5、2.8;6-3.0T...

(5)第5位:车身类型

A-四门三厢、B-四门两厢、C-四门方背

(6)第6位:发动机变速箱

1-手动汽油、2-自动汽油、3-手动柴油、4-自动柴油

(7)第7-8位:车型代码

(8)第9位:校验码

第九为实校验码,只能是数字0-9或X,它是由其他16位字码对应数值乘以其所位置权数的和除以11所得的余数;当余数为0-9时候,余数就是检验数字;当余数为10时,X为检验代码。校验码的目的就是核对数字,检验VIN填写是否正确,并能防止假冒产品

数字及英文字母对应值:

VIN码位置对应的加权系数

 

(9)第10位:出厂年份

(10)第11位:车辆组装地(装配厂)

(11)第12~17位:出厂顺序代码

这六位数由厂家自行决定第12-13代码可由0-9和A-Z(除'I'、'O'、'Q'外);第14-17,这最后四位则必须也只能为0-9的数字。

以上车架号解析转载于:汽车车架号怎么看? - Do it的回答 - 知乎 https://www.zhihu.com/question/302148790/answer/860621121

2、生成车架号可能需要的字符

/**车架号地区代码数组*/
    public static final String[] areaArray = new String[]{"1", "2", "3", "6", "9", "J", "K", "L", "R", "S", "T", "V", "W", "Y", "Z", "G"};

    /**车架号中可能出现的字符数组*/
    public static final String[] charArray = new String[]{"1", "2", "3", "4", "5", "6", "7", "8", "A", "B", "C", "D", "E", "F", "G", "H", "J", "K", "L", "M", "N", "P", "R", "S", "T", "V", "W", "X", "Y"};

    /**车架号校验位计算数组*/
    public static final char[][] KVMACTHUP = new char[][]{{'A', 1}, {'B', 2}, {'C', 3}, {'D', 4}, {'E', 5}, {'F', 6},{'G', 7}, {'H', 8}, {'I', 0}, {'J', 1}, {'K', 2}, {'L', 3},{'M', 4}, {'N', 5}, {'O', 0}, {'P', 7}, {'Q', 8}, {'R', 9}, {'S', 2}, {'T', 3}, {'U', 4}, {'V', 5}, {'W', 6}, {'X', 7},{'Y', 8}, {'Z', 9}};
    /**车架号数据加权数组*/
    public static final int[] WEIGHTVALUE = new int[]{8, 7, 6, 5, 4, 3, 2, 10, 0, 9, 8, 7, 6, 5, 4, 3, 2};
    public static final String[] strYear = new String[]{"1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F" ,"G", "H" ,"J" ,"K" ,"L" ,"M" ,"N" ,"P" ,"R" ,"S" ,"T" ,"V" ,"W" ,"X" ,"Y"};
    /**出厂顺序代码(第12~13位)*/
    public static final String[] strCode = new String[]{"0","1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F" ,"G", "H" ,"J" ,"K" ,"L" ,"M" ,"N" ,"P" ,"R" ,"S" ,"T" ,"V" ,"W" ,"X" ,"Y"};
    /**出厂顺序代码(第14~17位)*/
    public static final String[] strCodeNo = new String[]{"0","1", "2", "3", "4", "5", "6", "7", "8", "9"};

 3、计算校验码

 ​​​​​​校验码,只能是数字0-9或X,它是由其他16位字码对应数值乘以其所位置权数的和除以11所得的余数;当余数为0-9时候,余数就是检验数字;当余数为10时,X为检验代码。

/**
     * 计算车架号的校验位
     * @return
     */
    public static String getIsuredCode(String vin) {
        char[] Vin = vin.toCharArray();
        int sum = 0,tempValue = 0;
        char temp;
        for (int i = 0; i < 17; i++) {
            if (Vin[i] >= 'a' && Vin[i] <= 'z') {
                temp = (char) (Vin[i] - 32);
            } else if ((Vin[i] >= 'A') && (Vin[i] <= 'Z')) {
                temp = Vin[i];
            } else if ((Vin[i] >= '0') && (Vin[i] <= '9')) {
                tempValue = Integer.parseInt(String.valueOf(Vin[i]));
                temp = Vin[i];
            } else {
                return "ERROR";
            }
            if ((temp >= 'A') && (temp <= 'Z')) {
                for (int j = 0; j < 26; j++) {
                    if (temp == KVMACTHUP[j][0]) {
                        tempValue = (int) KVMACTHUP[j][1];
                    }
                }
            }
            sum += tempValue * WEIGHTVALUE[i];
        }
        int reslt = sum % 11;
        if (reslt != 10) {
            return String.valueOf(reslt);
        } else {
            return "X";
        }
    }

4、通过判断车架号的第9位是否是正确的校验码,判断车架号vin是否正确

/**
     * 判断vin是否正确
     * @param vin
     * @return
     */
    public static boolean isVin(String vin) {
        String isuredCode = getIsuredCode(vin);
        if (vin.substring(8, 9).equals(isuredCode)) {
            return true;
        } else {
            return false;
        }
    }

5、生成随机车辆特征

/**
     * 生成随机车辆特征
     *
     * @return
     */
    public static String prepareBeforeStr() {
        StringBuilder stringBuffer = new StringBuilder();
        stringBuffer.append("LFV");
        for (int i = 0; i < 5; i++) {
            stringBuffer.append(getRandomChar(areaArray));
        }
        return stringBuffer.toString();
    }

6、生成随机年份代码

/**
     * 生成随机年份代码
     *
     * @return
     */
    public static String prepareAfterStr() {
        StringBuilder stringBuffer = new StringBuilder();
        Random random = new Random();
        for (int i = 0; i < 1; i++) {
            stringBuffer.append(strYear[random.nextInt(strYear.length)]);
        }
        stringBuffer.append(prepareNo());
        return stringBuffer.toString();
    }

7、 生成随机的生产序号

第11位:车辆组装地(装配厂),第12-13代码可由0-9和A-Z(除'I'、'O'、'Q'外);第14-17,这最后四位则必须也只能为0-9的数字。

/**
     * 生成随机的生产序号
     * @return
     */
    public static String prepareNo(){
        Random random = new Random();
        StringBuilder numStrBuff = new StringBuilder();
        for(int i=0;i<3;i++){
            numStrBuff.append(strCode[random.nextInt(strCode.length)]);//第11~13位车架号
        }
        for (int i=0;i<4;i++){
            numStrBuff.append(strCodeNo[random.nextInt(strCodeNo.length)]);//第14~17位车架号
        }
        return numStrBuff.toString();
    }

8、拼接车架号

/**
     * 拼接车架号
     *
     * @param beforeStr
     * @param afterStr
     * @return
     */
    public static String spellVin(String beforeStr, String afterStr) {
        StringBuffer vinBuffer = new StringBuffer();
        String preVin = vinBuffer.append(beforeStr).append("X").append(afterStr).toString();
        String isuredCode = getIsuredCode(preVin);
        String vin = new StringBuffer(beforeStr).append(isuredCode).append(afterStr).toString();
        if (isVin(vin)) {
            return vin;
        } else {
            return spellVin(beforeStr, afterStr);
        }
    }

 9、返回随机字符

/**
     * 返回随机字符
     * @return
     */
    public static String getRandomChar(Object array[]) {
        Random random = new Random();
        return charArray[random.nextInt(array.length)];
    }

 10、获取随机车架号

public static String getRandomVin() {
        String beforeStr = prepareBeforeStr();
        String afterStr = prepareAfterStr();
        String vin = spellVin(beforeStr, afterStr);
        return vin;
    }

11、获取对应数量的随机车架号

public static List<String> getVinList(int num){
        List<String> vinList = new ArrayList<String>();
        for(int i =0;i<num;i++){
            vinList.add(getRandomVin());
        }
        return vinList;
    }

 12、随机获取重复的车架号

public static List<String> VinList(List<String> vinlist,int num){
        List<String> list = new ArrayList<String>();
        Random random = new Random();
        for (int i =0;i<num;i++){
            list.add(vinlist.get(random.nextInt(vinlist.size())));
        }
        return list;
    }

三、随机生成车架号代码整理

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class Vin {
    /**车架号地区代码数组*/
    public static final String[] areaArray = new String[]{"1", "2", "3", "6", "9", "J", "K", "L", "R", "S", "T", "V", "W", "Y", "Z", "G"};

    /**车架号中可能出现的字符数组*/
    public static final String[] charArray = new String[]{"1", "2", "3", "4", "5", "6", "7", "8", "A", "B", "C", "D", "E", "F", "G", "H", "J", "K", "L", "M", "N", "P", "R", "S", "T", "V", "W", "X", "Y"};

    /**车架号校验位计算数组*/
    public static final char[][] KVMACTHUP = new char[][]{{'A', 1}, {'B', 2}, {'C', 3}, {'D', 4}, {'E', 5}, {'F', 6},{'G', 7}, {'H', 8}, {'I', 0}, {'J', 1}, {'K', 2}, {'L', 3},{'M', 4}, {'N', 5}, {'O', 0}, {'P', 7}, {'Q', 8}, {'R', 9}, {'S', 2}, {'T', 3}, {'U', 4}, {'V', 5}, {'W', 6}, {'X', 7},{'Y', 8}, {'Z', 9}};
    /**车架号数据加权数组*/
    public static final int[] WEIGHTVALUE = new int[]{8, 7, 6, 5, 4, 3, 2, 10, 0, 9, 8, 7, 6, 5, 4, 3, 2};
    /**生产年份代码(第12~13位)*/
    public static final String[] strYear = new String[]{"1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F" ,"G", "H" ,"J" ,"K" ,"L" ,"M" ,"N" ,"P" ,"R" ,"S" ,"T" ,"V" ,"W" ,"X" ,"Y"};
    /**出厂顺序代码(第12~13位)*/
    public static final String[] strCode = new String[]{"0","1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F" ,"G", "H" ,"J" ,"K" ,"L" ,"M" ,"N" ,"P" ,"R" ,"S" ,"T" ,"V" ,"W" ,"X" ,"Y"};
    /**出厂顺序代码(第14~17位)*/
    public static final String[] strCodeNo = new String[]{"0","1", "2", "3", "4", "5", "6", "7", "8", "9"};
    /**
     * 计算车架号的校验位
     * @return
     */
    public static String getIsuredCode(String vin) {
        char[] Vin = vin.toCharArray();
        int sum = 0,tempValue = 0;
        char temp;
        for (int i = 0; i < 17; i++) {
            if (Vin[i] >= 'a' && Vin[i] <= 'z') {
                temp = (char) (Vin[i] - 32);
            } else if ((Vin[i] >= 'A') && (Vin[i] <= 'Z')) {
                temp = Vin[i];
            } else if ((Vin[i] >= '0') && (Vin[i] <= '9')) {
                tempValue = Integer.parseInt(String.valueOf(Vin[i]));
                temp = Vin[i];
            } else {
                return "ERROR";
            }
            if ((temp >= 'A') && (temp <= 'Z')) {
                for (int j = 0; j < 26; j++) {
                    if (temp == KVMACTHUP[j][0]) {
                        tempValue = (int) KVMACTHUP[j][1];
                    }
                }
            }
            sum += tempValue * WEIGHTVALUE[i];
        }
        int reslt = sum % 11;
        if (reslt != 10) {
            return String.valueOf(reslt);
        } else {
            return "X";
        }
    }
    /**
     * 判断vin是否正确
     * @param vin
     * @return
     */
    public static boolean isVin(String vin) {
        String isuredCode = getIsuredCode(vin);
        if (vin.substring(8, 9).equals(isuredCode)) {
            return true;
        } else {
            return false;
        }
    }
    /**
     * 拼接车架号
     *
     * @param beforeStr
     * @param afterStr
     * @return
     */
    public static String spellVin(String beforeStr, String afterStr) {
        StringBuffer vinBuffer = new StringBuffer();
        String preVin = vinBuffer.append(beforeStr).append("X").append(afterStr).toString();
        String isuredCode = getIsuredCode(preVin);
        String vin = new StringBuffer(beforeStr).append(isuredCode).append(afterStr).toString();
        if (isVin(vin)) {
            return vin;
        } else {
            return spellVin(beforeStr, afterStr);
        }
    }

    /**
     * 生成随机车辆特征
     *
     * @return
     */
    public static String prepareBeforeStr() {
        StringBuilder stringBuffer = new StringBuilder();
        stringBuffer.append("LFV");
        for (int i = 0; i < 5; i++) {
            stringBuffer.append(getRandomChar(areaArray));
        }
        return stringBuffer.toString();
    }

    /**
     * 生成随机年份
     *
     * @return
     */
    public static String prepareAfterStr() {
        StringBuilder stringBuffer = new StringBuilder();
        Random random = new Random();
        for (int i = 0; i < 1; i++) {
            stringBuffer.append(strYear[random.nextInt(strYear.length)]);
        }
        stringBuffer.append(prepareNo());
        return stringBuffer.toString();
    }

    /**
     * 生成随机的生产序号
     * @return
     */
    public static String prepareNo(){
        Random random = new Random();
        StringBuilder numStrBuff = new StringBuilder();
        for(int i=0;i<3;i++){
            numStrBuff.append(strCode[random.nextInt(strCode.length)]);//第11~13位车架号
        }
        for (int i=0;i<4;i++){
            numStrBuff.append(strCodeNo[random.nextInt(strCodeNo.length)]);//第14~17位车架号
        }
        return numStrBuff.toString();
    }
    /**
     * 返回随机字符
     * @return
     */
    public static String getRandomChar(Object array[]) {
        Random random = new Random();
        return charArray[random.nextInt(array.length)];
    }
    /**
     * 获取随机的车架号
     * @return
     */
    public static String getRandomVin() {
        String beforeStr = prepareBeforeStr();
        String afterStr = prepareAfterStr();
        String vin = spellVin(beforeStr, afterStr);
        return vin;
    }

    /**
     * 获取对应数量的随机车架号
     * @param num
     * @return
     */
    public static List<String> getVinList(int num){
        List<String> vinList = new ArrayList<String>();
        for(int i =0;i<num;i++){
            vinList.add(getRandomVin());
        }
        return vinList;
    }
    public static List<String> VinList(List<String> vinlist,int num){
        List<String> list = new ArrayList<String>();
        Random random = new Random();
        for (int i =0;i<num;i++){
            list.add(vinlist.get(random.nextInt(vinlist.size())));
        }
        return list;
    }
}

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值