Java常见应用——Json,二维码生成,加密解密应用

一.JSON

1.下载json架包,json官网:json.org

2.将Map/JavaBean/String转化成json对象,只需要使用JSONObject的构造方法即可

package com.nike.app.json;import com.nike.app.reflect.Address;
import com.nike.app.reflect.Student;
import org.json.JSONObject;import java.util.HashMap;
import java.util.Map;public class Demo01 {/*** Map集合转Json对象*/public static void mapToJson(){Map<String,String> map = new HashMap<>();map.put("name","zhangsan");map.put("age","22");map.put("gender","man");//map->jsonJSONObject mjson = new JSONObject(map);System.out.println(mjson);//{"gender":"man","name":"zhangsan","age":"22"}}public static void beanToJson(){Student stu = new Student("NikeHu",99,new Address("陕西省","西安市","高新区","高新四路"));JSONObject bjson = new JSONObject(stu);System.out.println(bjson);//{"score":99,"address":{"area":"高新区","province":"陕西省","city":"西安市","street":"高新四路"},"name":"NikeHu"}}public static void strToJson(){String str = "{\"score\":99,\"address\":{\"area\":\"高新区\",\"province\":\"陕西省\",\"city\":\"西安市\",\"street\":\"高新四路\"},\"name\":\"NikeHu\"}";JSONObject sjson = new JSONObject(str);System.out.println(sjson);//{"score":99,"address":{"area":"高新区","province":"陕西省","city":"西安市","street":"高新四路"},"name":"NikeHu"}}public static void main(String[] args) {strToJson();}
}

3.读取文件,转化为Json对象

package com.nike.app.json;import org.apache.commons.io.FileUtils;
import org.json.JSONObject;import java.io.File;
import java.io.IOException;
import java.io.InputStream;/*** 读取json文件,并将其转化为json对象*/
public class Demo02 {public void demo01() throws IOException {InputStream input = super.getClass().getClassLoader().getResourceAsStream("com/nike/app/json/per.json");byte[] buf = new byte[10];int len = -1;StringBuffer sb = new StringBuffer();while ((len=input.read(buf))!=-1){sb.append(new String(buf,0,len));}JSONObject jsonObject = new JSONObject(sb.toString());System.out.println(jsonObject);//{"address":{"schooladdress":"shanghai","homeaddress":"xian"},"gender":"man","name":"zhangsan","tel":"15682341831","age":22}}/*** 使用commons-io包将文件转化成字符串*/public static void demo02() throws IOException {String str = FileUtils.readFileToString(new File("E:\\IdeaProjects\\JavaApp\\src\\com\\nike\\app\\json\\per.json"), "UTF-8");JSONObject jobj = new JSONObject(str);System.out.println(jobj);//{"address":{"schooladdress":"shanghai","homeaddress":"xian"},"gender":"man","name":"zhangsan","tel":"15682341831","age":22}}public static void main(String[] args) {Demo02 demo = new Demo02();try {demo.demo01();demo02();} catch (IOException e) {e.printStackTrace();}}
}

4.生成json文件

package com.nike.app.json;import com.nike.app.reflect.Address;
import com.nike.app.reflect.Student;
import org.json.JSONObject;import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;public class Demo03 {public static void jsonToFile() throws IOException {Student stu01 = new Student("NikeHu",99,new Address("陕西省","西安市","高新区","高新四路"));Student stu02 = new Student("Mike",77,new Address("陕西省","西安市","高新区","高新四路"));Student stu03 = new Student("Alex",88,new Address("陕西省","西安市","高新区","高新四路"));Map<String,Student> stus = new HashMap<>();stus.put("nike",stu01);stus.put("Mike",stu02);stus.put("Alex",stu03);JSONObject bjson = new JSONObject(stus);System.out.println(bjson);//{"score":99,"address":{"area":"高新区","province":"陕西省","city":"西安市","street":"高新四路"},"name":"NikeHu"}FileWriter fw = new FileWriter("stu.json");bjson.write(fw);fw.close();}public static void main(String[] args) {try {jsonToFile();} catch (IOException e) {e.printStackTrace();}}
}
{"Alex":{"score":88,"address":{"area":"高新区","province":"陕西省","city":"西安市","street":"高新四路"},"name":"Alex"},"Mike":{"score":77,"address":{"area":"高新区","province":"陕西省","city":"西安市","street":"高新四路"},"name":"Mike"},"nike":{"score":99,"address":{"area":"高新区","province":"陕西省","city":"西安市","street":"高新四路"},"name":"NikeHu"}}

5.JsonArray

package com.nike.app.json;import org.json.JSONArray;import java.util.HashMap;
import java.util.Map;public class Demo04 {//字符串转json数组public static void demo01(){/**JsonArray* [{"name":"zhangsan","age":22},{"classname":"class1","classno":1},{"province":"shanxi","city":"xianyan"}]*/String jsonArrayStr = "[{\"name\":\"zhangsan\",\"age\":22},{\"classname\":\"class1\",\"classno\":1},{\"province\":\"shanxi\",\"city\":\"xianyan\"}]";JSONArray ja = new JSONArray(jsonArrayStr);System.out.println(ja);//[{"name":"zhangsan","age":22},{"classname":"class1","classno":1},{"province":"shanxi","city":"xianyan"}]}//Map对象转json数据//对于json的类型转换,通常需要引入另一个json库json-libpublic static void demo02(){Map<String,String> map = new HashMap<>();map.put("key1","value1");map.put("key2","value2");map.put("key3","value3");map.put("key4","value4");map.put("key5","value5");map.put("key6","value6");net.sf.json.JSONArray jsonArray = new net.sf.json.JSONArray();jsonArray = jsonArray.fromObject(map);System.out.println(jsonArray);//[{"key1":"value1","key2":"value2","key5":"value5","key6":"value6","key3":"value3","key4":"value4"}]}public static void main(String[] args) {demo01();demo02();}
}

二.二维码生成

使用Java生成二维码

1.QRCode 日本

package com.nike.app.qrcode;import com.swetake.util.Qrcode;import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.io.File;public class QRCodeUtils {//加密:文字信息->二维码public static void encodeQR(String info,String imgPath,String type,int size) throws Exception{File file = new File(imgPath);//BufferedImage 内存中的一张图片BufferedImage bufImg = qRcodeCommon(info,type,size);//生成图片ImageIO.write(bufImg,type,file);}/*** 产生一个二维码的BufferedImage* @param content 二维码中的隐藏信息* @param format 二维码格式* @param size 图片大小相关参数* @return*/public static BufferedImage qRcodeCommon(String content,String format,int size) throws Exception{int length = 67 + 12 * (size-1);BufferedImage bufimg = null;bufimg = new BufferedImage(length,length,BufferedImage.TYPE_INT_RGB);Graphics2D graphics = bufimg.createGraphics();//将图片的背景色设为白色graphics.setBackground(Color.WHITE);//初始化白色背景graphics.clearRect(0,0,length,length);//设置画板上二维码的颜色graphics.setColor(Color.black);//String->boolean[][]:Qrcode对象Qrcode qrcode = new Qrcode();//设置二维码的排错率:L|M|Q|H:排错率越高,可存储的信息越少,但是对二维码清晰度要求越小qrcode.setQrcodeErrorCorrect('M');//设置二维码可存放的信息类型:N(数字),A(数字+A-Z),B(所有)qrcode.setQrcodeEncodeMode('B');//二维码尺寸取值范围:1-40(数字越大,二维码越大)qrcode.setQrcodeVersion(size);//将字节数组转化成布尔值二维数组boolean[][] codeOut = qrcode.calQrcode(content.getBytes());int pixoff = 2;for (int i = 0; i < codeOut.length; i++) {for (int j = 0; j < codeOut[i].length; j++) {if (codeOut[i][j]){graphics.fillRect(2+3*j,2+3*i,3,3);}}}graphics.dispose();bufimg.flush();return bufimg;}//解密:二维码->文字信息
}
package com.nike.app.qrcode;/*** 生成二维码* 生成图片的路径 qr01.png* 文字信息,网址信息:"1506214574"*/
public class Test01 {static String imgPath = "E:\\img\\qr01.png";static String content = "150621457";/*** 生成二维码* 加密:文字信息->二维码* 解密:二维码->文字信息*/public static void main(String[] args) throws Exception {QRCodeUtils.encodeQR(content,imgPath,"png",7);}
}
在二维码图片中心加上logo
package com.nike.app.qrcode;import com.swetake.util.Qrcode;
import jp.sourceforge.qrcode.QRCodeDecoder;
import jp.sourceforge.qrcode.data.QRCodeImage;import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.io.File;
import java.io.IOException;public class QRCodeUtils {//加密:文字信息->二维码public static void encodeQR(String info,String imgPath,String type,int size) throws Exception{File file = new File(imgPath);//BufferedImage 内存中的一张图片BufferedImage bufImg = qRcodeCommon(info,type,size);//生成图片ImageIO.write(bufImg,type,file);}/*** 产生一个二维码的BufferedImage* @param content 二维码中的隐藏信息* @param format 二维码格式* @param size 图片大小相关参数* @return*/public static BufferedImage qRcodeCommon(String content,String format,int size) throws Exception{int length = 67 + 12 * (size-1);BufferedImage bufimg = null;bufimg = new BufferedImage(length,length,BufferedImage.TYPE_INT_RGB);Graphics2D graphics = bufimg.createGraphics();//将图片的背景色设为白色graphics.setBackground(Color.WHITE);//初始化白色背景graphics.clearRect(0,0,length,length);//设置画板上二维码的颜色graphics.setColor(Color.black);//String->boolean[][]:Qrcode对象Qrcode qrcode = new Qrcode();//设置二维码的排错率:L|M|Q|H:排错率越高,可存储的信息越少,但是对二维码清晰度要求越小qrcode.setQrcodeErrorCorrect('L');//设置二维码可存放的信息类型:N(数字),A(数字+A-Z),B(所有)qrcode.setQrcodeEncodeMode('B');//二维码尺寸取值范围:1-40(数字越大,二维码越大)qrcode.setQrcodeVersion(size);//将字节数组转化成布尔值二维数组boolean[][] codeOut = qrcode.calQrcode(content.getBytes("utf-8"));int pixoff = 2;for (int i = 0; i < codeOut.length; i++) {for (int j = 0; j < codeOut[i].length; j++) {if (codeOut[j][i]){graphics.fillRect(2+3*j,2+3*i,3,3);}}}//增加Logo//将硬盘中的图片加载为Image对象Image logo = ImageIO.read(new File("src/logo.jpg"));//获取二维码区域的宽高int qrheight = bufimg.getHeight();int qrwidth = bufimg.getWidth();//在已生成的二维码图片上画logographics.drawImage(logo,length*2/5,length*2/5,qrwidth/5,qrheight/5,null);graphics.dispose();bufimg.flush();return bufimg;}//解密:二维码->文字信息public static String decodeQR(String imgPath) throws Exception {//将硬盘中的图片加载到内存中。BufferedImage bufimg = ImageIO.read(new File(imgPath));QRCodeDecoder decoder = new QRCodeDecoder();QRCodeImage qrCodeImage = new QRCodeImageImpl(bufimg);byte[] bytes = decoder.decode(qrCodeImage);return new String(bytes,"utf-8");}
}
package com.nike.app.qrcode;import jp.sourceforge.qrcode.data.QRCodeImage;import java.awt.image.BufferedImage;public class QRCodeImageImpl implements QRCodeImage {BufferedImage bufferedImage;public QRCodeImageImpl(BufferedImage bufferedImage){this.bufferedImage = bufferedImage;}@Overridepublic int getWidth() {return bufferedImage.getWidth();}@Overridepublic int getHeight() {return bufferedImage.getHeight();}@Overridepublic int getPixel(int x, int y) {return bufferedImage.getRGB(x,y);}
}
package com.nike.app.qrcode;/*** 生成二维码* 生成图片的路径 qr01.png* 文字信息,网址信息:"1506214574"*/
public class Test01 {static String imgPath = "E:\\img\\qr01.png";static String content = "1506214574";/*** 生成二维码* 加密:文字信息->二维码* 解密:二维码->文字信息*/public static void main(String[] args) throws Exception {QRCodeUtils.encodeQR(content,imgPath,"png",17);String s = QRCodeUtils.decodeQR(imgPath);System.out.println(s);}
}

2.ZXing Google

package com.nike.app.zxing;import com.google.zxing.*;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;import javax.imageio.ImageIO;import java.awt.*;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;public class ZXingUtils {//加密:文字信息->二维码/**** @param imgPath 生成的二维码图片的保存路径* @param format 图片格式* @param content 二维码保存的信息* @param width* @param height* @throws Exception*/public static void encodeZX(String imgPath,String format,String content,int width,int height) throws Exception {File file = new File(imgPath);/**hints存放加密参数* 编码格式,排错率,*/Map<EncodeHintType,Object> hints = new Hashtable<>();hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);hints.put(EncodeHintType.CHARACTER_SET,"UTF-8");hints.put(EncodeHintType.MARGIN,1);//BarcodeFormat.QR_CODE:要解析的类型(二维码)BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE,width,height,hints);BufferedImage bufimg = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);for (int x=0;x < width;x++){for (int y=0;y<height;y++){bufimg.setRGB(x,y,(bitMatrix.get(x,y)? Color.BLACK:Color.WHITE).getRGB());}}String logo = "src/logo.jpg";bufimg = addLogo(bufimg,logo);//生成图片:format:图片格式ImageIO.write(bufimg,format,file);}public static BufferedImage addLogo(BufferedImage bufimg,String logoPath) throws Exception {//生成一个二维画板Graphics2D graph = bufimg.createGraphics();BufferedImage logoImg = ImageIO.read(new File(logoPath));int width = bufimg.getWidth();int height = bufimg.getHeight();graph.drawImage(logoImg,width*2/5,height*2/5,width/5,height/5,null);//产生一个画白色边框的画笔BasicStroke stroke = new BasicStroke(5,BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND);//关联画板画笔graph.setStroke(stroke);//画logo外的圆角矩形边框RoundRectangle2D.Float round = new RoundRectangle2D.Float(width*2/5,height*2/5,width/5,height/5,BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND);graph.setColor(Color.WHITE);graph.draw(round);//画灰色外边框//产生一个画灰色边框的画笔BasicStroke stroke01 = new BasicStroke(1,BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND);//关联画板画笔graph.setStroke(stroke);//画logo外的圆角矩形边框RoundRectangle2D.Float round01 = new RoundRectangle2D.Float(width*2/5+2,height*2/5+2,width/5-4,height/5-4,BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND);graph.setColor(Color.GRAY);graph.draw(round01);//释放空间graph.dispose();bufimg.flush();return bufimg;}//解密:二维码->文字信息public static String decodeZX(File file) throws Exception {if (!file.exists()){ return ""; }//将文件读取到内存中BufferedImage bufImg = ImageIO.read(file);MultiFormatReader reader = new MultiFormatReader();Map hints = new HashMap();hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);hints.put(EncodeHintType.CHARACTER_SET,"UTF-8");hints.put(EncodeHintType.MARGIN,1);LuminanceSource source = new BufferedImageLuminanceSource(bufImg);Binarizer binarizer = new HybridBinarizer(source);BinaryBitmap bitmap = new BinaryBitmap(binarizer);Result result = reader.decode(bitmap,hints);return result.toString();}
}
package com.nike.app.zxing;import java.io.File;public class Test01 {public static void main(String[] args) throws Exception {String imgPath = "E:\\img\\zxing03.gif";String imgInfo = "猪猪,我爱你";//加密//解密ZXingUtils.encodeZX(imgPath,"gif",imgInfo,450,450);System.out.println(ZXingUtils.decodeZX(new File(imgPath)));}
}

三.加密解密应用

1.异或加密,解密

异或:

  • 同为0,异为1;
  • 一个数经历两次异或后,是原数本身。

假设a为01100011,则a与3异或的结果为:

a^3 = 01100011^00000011=
---------------------------------------------------------------------------------------------------
第一次异或:01100011
^00000011
=01100000
---------------------------------------------------------------------------------------------------
第二次异或:01100000
^00000011
=01100011
---------------------------------------------------------------------------------------------------
package com.nike.app.security;public class SecutityUtils {//密钥private static final int SECRET_KEY=3000;/*** 1.通过异或实现加密解密* (1).一次异或为加密* (2).两次异或为解密* @param clearText 需要加密的明文* @return cipherText 加密后的密文*/public static String XORencode(String clearText){String cipherText = null;//1.将传入的明文参数转化成字符数组char[] chs = clearText.toCharArray();for (int i = 0; i < chs.length; i++) {//对每一位字符进行异或加密chs[i] = (char)(chs[i] ^ 3000);}cipherText = new String(chs);return cipherText;}
}
package com.nike.app.security;public class Text {public static void main(String[] args) {String str = SecutityUtils.XORencode("猪猪,我爱你");System.out.println(str);System.out.println(SecutityUtils.XORencode(str));/**输出的结果为:* ௐ௝௔௔ௗ* hello*/}
}

2.MD5和SHA加密,解密

字符串转为成十六进制串,且该过程是不可逆的。

MD5:不可逆,速度较快

SHA256:不可逆,安全性较高

添加加密jar包:commons-codec.jar

(1)MD5加密

package com.nike.app.security;import org.apache.commons.codec.digest.DigestUtils;public class MD5Utils {/*** 简单加密* @param input* @return cipherText*/public static String md5Encode(byte[] input){String cipherText = DigestUtils.md5Hex(input);return cipherText;}
}

(2)SHA256加密

package com.nike.app.security;import org.apache.commons.codec.digest.DigestUtils;public class SHA256Utils {public static String sha256Encode(byte[] input){return DigestUtils.sha256Hex(input);}
}

测试:

package com.nike.app.security;public class Test {public static void main(String[] args) {String clearText = "Hello";System.out.println(MD5Utils.md5Encode(clearText.getBytes()));//8b1a9953c4611296a827abf8c47804d7System.out.println(SHA256Utils.sha256Encode(clearText.getBytes()));//185f8db32271fe25f561a6fc938b2e264306ec304eda518007d1764826381969}
}

3.BASE64加密,解密

package com.nike.app.security;import java.lang.reflect.Method;public class Base64Utils {/*** Base64加密* @param input* @return*/public static String base64Encode(byte[] input){String result = null;try {Class Base64Class = Class.forName("com.sun.org.apache.xerces.internal.impl.dv.util.Base64");Method encode = Base64Class.getMethod("encode", byte[].class);result = (String)encode.invoke(null, input);} catch (Exception e) {e.printStackTrace();}return result;}/*** Base64解密* @param input* @return*/public static byte[] base64Decode(String input){byte[] result = null;try {Class Base64Class = Class.forName("com.sun.org.apache.xerces.internal.impl.dv.util.Base64");Method decode = Base64Class.getMethod("decode", String.class);result = (byte[])decode.invoke(null, input);} catch (Exception e) {e.printStackTrace();}return result;}
}
package com.nike.app.security;public class Test {public static void main(String[] args) {String clearText = "Hello";//Base64加密String str = Base64Utils.base64Encode(clearText.getBytes());System.out.println(str);//SGVsbG8=//Base64解密byte[] bytes = Base64Utils.base64Decode(str);System.out.println(new String(bytes));//hello}
}

Java常见应用——Json,二维码生成,加密解密应用相关推荐

  1. JAVA实现QRCode的二维码生成以及打印

    喜欢的朋友可以关注下,粉丝也缺. 不说废话了直接上代码 注意使用QRCode是需要zxing的核心jar包,这里给大家提供下载地址 https://download.csdn.net/download ...

  2. java二维码生成并可以转换

    二维码很常见,简单的二维码生成 pom中导入两个包 <!--二维码--><dependency><groupId>com.google.zxing</grou ...

  3. java调用热敏打印机打印(包含二维码生成)

    项目中需要用到热敏打印机,并且在打印的同时,要生成二维码.并且打印,先说说二维码的生成吧 package com.jinke.util; import com.google.zxing.common. ...

  4. SpringBoot 二维码生成base64并上传OSS

    SpringBoot 二维码生成base64并上传OSS 基础环境 SpringBoot.Maven 代码实现 1.添加依赖 <!--二维码生成 --> <dependency> ...

  5. 二维码 生成工具类(文件转Base64字符串,Base64字符串转文件)

    希望我的知识榨干了能帮到你解除困难,要是没有帮助你的,问度娘和知爹 一.POM.xml依赖下载 二.工具类提供 一.POM.xml依赖下载 <!-- 生成二维码依赖 --><depe ...

  6. java 二维码生成及其标签打印

    本文主要内容 二维码生成 二维码标签预览及打印 二维码生成 笔者此次的二维码是通过调用第三方接口生成的,具体流程如下: 根据规范要求调用第三方接口,返回二维码下载地址及二维码图片的属性值(图片大小等) ...

  7. java 二维码生成和加密base64压码

    因为项目中要实现扫描二维码并实现登录,但本人开发的模块是服务器,跟前台传输用到的主要是json对象.所以不能直接传输图片,必须把图片加密成base64压码的形式. 首先介绍二维码生成的代码,二维码生成 ...

  8. Marco's Java【小工具篇 之 Google Zxing 二维码生成】

    前言 二维码相信大家一定不陌生啦,去菜市场买菜,路边摊买个小吃都可以扫一扫,近几年来中国的二维码技术的普及也是大家有目共睹的,而二维码在其他国家虽然有用到,但极少,更没有说全国普及. 二维码又称二维条 ...

  9. java实现二维码生成的几个方法

    java实现二维码生成的几个方法 分类: J2EE2013-06-13 20:32 10390人阅读 评论(1) 收藏 举报 1: 使用SwetakeQRCode在Java项目中生成二维码  http ...

最新文章

  1. mysql 取二进制某一位_c语言中如何提取二进制数中的某一位?
  2. 如何检查电脑是否安装了python-python-如何检查安装了scikit的nltk版本?
  3. Linux MISC 驱动实验
  4. P4549-[模板]裴蜀定理
  5. 机器学习从理论到工程的第一步-编程语言篇
  6. Spring自学日志02(对象的创建,依赖注入)
  7. Mysql 添加用户 授权等操作
  8. [SHELL] LAMP一键安装脚本设计(v2.1)
  9. 11、doCreateBean中的initializeBean
  10. 如何编译 opencv3 和 opencv_contrib(Linux)
  11. java session机制_如何学习Session的机制使用
  12. Extjs 例外被抛出且未被接住
  13. OLS回归模型-斯皮尔曼相关系数-数值模拟-多目标规划-养老服务床位需求预测与运营模式研究-之数学建模
  14. 一图囊括所有ES6知识点结构
  15. 如何用计算机扫描图片变成文字,如何把文字图片或者扫描的文件变成word文档?详细步骤...
  16. Android studio实现类微信界面
  17. Graham算法解决凸包问题
  18. php导出word文件(二)
  19. ATECC608A的完美兼容国产替代芯片
  20. python 线程 (概念+示例代码)

热门文章

  1. RocketMQ学习笔记二之【DefaultMQPushConsumer使用与流程原理分析】
  2. spring boot 注解实现mock数据
  3. 基于大数据的移动端茶叶销售系统(附源码)
  4. UG11.0压铸模具基础知识讲解视频教程 产品处理 修改教程
  5. 强制卸载额外域控制器
  6. python正则表达式的几个匹配函数用法
  7. ionic上传身份证正反面照片、上传图片、FileReader使用
  8. 【Lesson1】「ALOS数据」SAR土地利用分类41
  9. Window10 安装Linux子系统
  10. DAX圣经学习笔记1 - 常用函数