0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

SpringBoot采用JsonSerializer和Aop实现可控制的数据脱敏

jf_ro2CN3Fa 来源:芋道源码 2023-11-06 16:15 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群


1 起因

最近在写一个功能,对用户敏感的数据进行脱敏,在网上看一圈基本上都是全局范围的,我觉得应该更加灵活,在不同场景,不同业务下进行脱敏更加合适。

JsonSerializer介绍就参考这位大佬的

https://juejin.cn/post/6872636051237240846

aop介绍参考这位大佬的

https://juejin.cn/post/6844903575441637390

基于 Spring Boot + MyBatis Plus + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能

  • 项目地址:https://github.com/YunaiV/ruoyi-vue-pro
  • 视频教程:https://doc.iocoder.cn/video/

2 初步尝试

枚举类

/**
*敏感信息枚举类
*
**/
publicenumPrivacyTypeEnum{

/**
*自定义
*/
CUSTOMER,
/**
*用户名,张*三,李*
*/
CHINESE_NAME,
/**
*身份证号,110110********1234
*/
ID_CARD,
/**
*座机号,****1234
*/
FIXED_PHONE,
/**
*手机号,176****1234
*/
MOBILE_PHONE,
/**
*地址,北京********
*/
ADDRESS,
/**
*电子邮件,s*****o@xx.com
*/
EMAIL,
/**
*银行卡,622202************1234
*/
BANK_CARD,
/**
*密码,永远是******,与长度无关
*/
PASSWORD,
/**
*密钥,永远是******,与长度无关
*/
KEY

}

注解

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD})//作用于字段上
@JacksonAnnotationsInside//表示自定义自己的注解PrivacyEncrypt
@JsonSerialize(using=PrivacySerialize.class)//该注解使用序列化的方式
public@interfacePrivacyEncrypt{

/**
*脱敏数据类型,非Customer时,将忽略refixNoMaskLen和suffixNoMaskLen和maskStr
*/
PrivacyTypeEnumtype()defaultPrivacyTypeEnum.CUSTOMER;

/**
*前置不需要打码的长度
*/
intprefixNoMaskLen()default0;

/**
*后置不需要打码的长度
*/
intsuffixNoMaskLen()default0;

/**
*用什么打码
*/
StringmaskStr()default"*";

}

序列化类

publicclassPrivacySerializeextendsJsonSerializer<String>implementsContextualSerializer{
publicstaticfinalLoggerlogger=LoggerFactory.getLogger(PrivacySerialize.class);
privatePrivacyTypeEnumtype;

privateIntegerprefixNoMaskLen;

privateIntegersuffixNoMaskLen;

privateStringmaskStr;

publicPrivacySerialize(PrivacyTypeEnumtype,IntegerprefixNoMaskLen,IntegersuffixNoMaskLen,StringmaskStr){
this.type=type;
this.prefixNoMaskLen=prefixNoMaskLen;
this.suffixNoMaskLen=suffixNoMaskLen;
this.maskStr=maskStr;
}
publicPrivacySerialize(){
}

@Override
publicvoidserialize(Stringorigin,JsonGeneratorjsonGenerator,SerializerProviderserializerProvider)throwsIOException{
if(StringUtils.isNotBlank(origin)&&null!=type){
switch(type){
caseCHINESE_NAME:
jsonGenerator.writeString(DesensitizedUtils.chineseName(origin));
break;
caseID_CARD:
jsonGenerator.writeString(DesensitizedUtils.idCardNum(origin));
break;
caseFIXED_PHONE:
jsonGenerator.writeString(DesensitizedUtils.fixedPhone(origin));
break;
caseMOBILE_PHONE:
jsonGenerator.writeString(DesensitizedUtils.mobilePhone(origin));
break;
caseADDRESS:
jsonGenerator.writeString(DesensitizedUtils.address(origin));
break;
caseEMAIL:
jsonGenerator.writeString(DesensitizedUtils.email(origin));
break;
caseBANK_CARD:
jsonGenerator.writeString(DesensitizedUtils.bankCard(origin));
break;
casePASSWORD:
jsonGenerator.writeString(DesensitizedUtils.password(origin));
break;
caseKEY:
jsonGenerator.writeString(DesensitizedUtils.key(origin));
break;
caseCUSTOMER:
jsonGenerator.writeString(DesensitizedUtils.desValue(origin,prefixNoMaskLen,suffixNoMaskLen,maskStr));
break;
default:
thrownewIllegalArgumentException("Unknowsensitivetypeenum"+type);
}
}else{
jsonGenerator.writeString("");
}

}

@Override
publicJsonSerializercreateContextual(SerializerProviderserializerProvider,BeanPropertybeanProperty)throwsJsonMappingException{
if(beanProperty!=null){
if(Objects.equals(beanProperty.getType().getRawClass(),String.class)){
PrivacyEncryptencrypt=beanProperty.getAnnotation(PrivacyEncrypt.class);
if(encrypt==null){
encrypt=beanProperty.getContextAnnotation(PrivacyEncrypt.class);
}
if(encrypt!=null){
returnnewPrivacySerialize(encrypt.type(),encrypt.prefixNoMaskLen(),
encrypt.suffixNoMaskLen(),encrypt.maskStr());
}
}
returnserializerProvider.findValueSerializer(beanProperty.getType(),beanProperty);
}
returnserializerProvider.findNullValueSerializer(null);
}
}

脱敏工具类

/**
*脱敏工具类
*
**/
publicclassDesensitizedUtils{

/**
*对字符串进行脱敏操作
*@paramorigin原始字符串
*@paramprefixNoMaskLen左侧需要保留几位明文字段
*@paramsuffixNoMaskLen右侧需要保留几位明文字段
*@parammaskStr用于遮罩的字符串,如'*'
*@return脱敏后结果
*/
publicstaticStringdesValue(Stringorigin,intprefixNoMaskLen,intsuffixNoMaskLen,StringmaskStr){
if(origin==null){
returnnull;
}

StringBuildersb=newStringBuilder();
for(inti=0,n=origin.length();i< n; i++) {
         if(i< prefixNoMaskLen) {
            sb.append(origin.charAt(i));
            continue;
}
if(i>(n-suffixNoMaskLen-1)){
sb.append(origin.charAt(i));
continue;
}
sb.append(maskStr);
}
returnsb.toString();
}

/**
*【中文姓名】只显示最后一个汉字,其他隐藏为星号,比如:**梦
*@paramfullName姓名
*@return结果
*/
publicstaticStringchineseName(StringfullName){
if(fullName==null){
returnnull;
}
returndesValue(fullName,0,1,"*");
}

/**
*【身份证号】显示前六位,四位,其他隐藏。共计18位或者15位,比如:340304*******1234
*@paramid身份证号码
*@return结果
*/
publicstaticStringidCardNum(Stringid){
returndesValue(id,6,4,"*");
}

/**
*【固定电话】后四位,其他隐藏,比如****1234
*@paramnum固定电话
*@return结果
*/
publicstaticStringfixedPhone(Stringnum){
returndesValue(num,0,4,"*");
}

/**
*【手机号码】前三位,后四位,其他隐藏,比如135****6810
*@paramnum手机号码
*@return结果
*/
publicstaticStringmobilePhone(Stringnum){
returndesValue(num,3,4,"*");
}

/**
*【地址】只显示到地区,不显示详细地址,比如:北京市海淀区****
*@paramaddress地址
*@return结果
*/
publicstaticStringaddress(Stringaddress){
returndesValue(address,6,0,"*");
}

/**
*【电子邮箱邮箱前缀仅显示第一个字母,前缀其他隐藏,用星号代替,@及后面的地址显示,比如:d**@126.com
*@paramemail电子邮箱
*@return结果
*/
publicstaticStringemail(Stringemail){
returnemail.replaceAll("(w?)(w+)(w)(@w+.[a-z]+(.[a-z]+)?)","$1****$3$4");

}

/**
*【银行卡号】前六位,后四位,其他用星号隐藏每位1个星号,比如:622260**********1234
*@paramcardNum银行卡号
*@return结果
*/
publicstaticStringbankCard(StringcardNum){
returndesValue(cardNum,6,4,"*");
}

/**
*【密码】密码的全部字符都用*代替,比如:******
*@parampassword密码
*@return结果
*/
publicstaticStringpassword(Stringpassword){
if(password==null){
returnnull;
}
return"******";
}

/**
*【密钥】密钥除了最后三位,全部都用*代替,比如:***xdS脱敏后长度为6,如果明文长度不足三位,则按实际长度显示,剩余位置补*
*@paramkey密钥
*@return结果
*/
publicstaticStringkey(Stringkey){
if(key==null){
returnnull;
}
intviewLength=6;
StringBuildertmpKey=newStringBuilder(desValue(key,0,3,"*"));
if(tmpKey.length()>viewLength){
returntmpKey.substring(tmpKey.length()-viewLength);
}
elseif(tmpKey.length()< viewLength) {
         intbuffLength=viewLength-tmpKey.length();
for(inti=0;i< buffLength; i++) {
            tmpKey.insert(0,"*");
}
returntmpKey.toString();
}
else{
returntmpKey.toString();
}
}

}

注解使用

d20e65cc-7c44-11ee-939d-92fbcf53809c.pngd2406482-7c44-11ee-939d-92fbcf53809c.png

的确实现了数据脱敏,但是有个问题现在的脱敏针对的是 只要对该实体类进行了使用返回的接口,中的数据都会进行脱敏,在有些场景下是不需要的,所以说要进行改进。

基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能

  • 项目地址:https://github.com/YunaiV/yudao-cloud
  • 视频教程:https://doc.iocoder.cn/video/

3 第二版改进

我的思路是在该实体类中在继承一个 父类其中定义一个字段,使其作为是否进行脱敏的开关,并且该实体类字段不参与序列化 脱敏控制类

publicclassDataMaskKeyimplementsSerializable{
//不进行序列化,设置key来进行过滤的把控,默认不开启
privatetransientBooleanisPrivacyKey=false;

publicBooleangetPrivacyKey(){
returnisPrivacyKey;
}

publicvoidsetPrivacyKey(BooleanprivacyKey){
isPrivacyKey=privacyKey;
}
}

更新之后的序列化类

思路就是通过反射获取,该成员的属性,因为不知道会继承多少,所以要进行递归查找需要的字段

publicclassPrivacySerializeextendsJsonSerializer<String>implementsContextualSerializer{
publicstaticfinalLoggerlogger=LoggerFactory.getLogger(PrivacySerialize.class);
privatePrivacyTypeEnumtype;

privateIntegerprefixNoMaskLen;

privateIntegersuffixNoMaskLen;

privateStringmaskStr;

publicPrivacySerialize(PrivacyTypeEnumtype,IntegerprefixNoMaskLen,IntegersuffixNoMaskLen,StringmaskStr){
this.type=type;
this.prefixNoMaskLen=prefixNoMaskLen;
this.suffixNoMaskLen=suffixNoMaskLen;
this.maskStr=maskStr;
}
publicPrivacySerialize(){
}

@Override
publicvoidserialize(Stringorigin,JsonGeneratorjsonGenerator,SerializerProviderserializerProvider)throwsIOException{
booleanflag=false;
//反射获取对象
ObjectcurrentValue=jsonGenerator.getOutputContext().getCurrentValue();
//反射获取class
ClassaClass=jsonGenerator.getOutputContext().getCurrentValue().getClass();
ListfieldList=getFieldList(aClass);
for(Fieldfield:fieldList){
//开始反射获取
Stringname=field.getName();
if("isPrivacyKey".equals(name)){
try{
//进行重新赋值
flag=(boolean)field.get(currentValue);
}catch(IllegalAccessExceptione){
e.printStackTrace();
}
}
}
//反射进行进行开关判定
if(flag){
//logger.info("进行脱敏处理");
if(StringUtils.isNotBlank(origin)&&null!=type){
switch(type){
caseCHINESE_NAME:
jsonGenerator.writeString(DesensitizedUtils.chineseName(origin));
break;
caseID_CARD:
jsonGenerator.writeString(DesensitizedUtils.idCardNum(origin));
break;
caseFIXED_PHONE:
jsonGenerator.writeString(DesensitizedUtils.fixedPhone(origin));
break;
caseMOBILE_PHONE:
jsonGenerator.writeString(DesensitizedUtils.mobilePhone(origin));
break;
caseADDRESS:
jsonGenerator.writeString(DesensitizedUtils.address(origin));
break;
caseEMAIL:
jsonGenerator.writeString(DesensitizedUtils.email(origin));
break;
caseBANK_CARD:
jsonGenerator.writeString(DesensitizedUtils.bankCard(origin));
break;
casePASSWORD:
jsonGenerator.writeString(DesensitizedUtils.password(origin));
break;
caseKEY:
jsonGenerator.writeString(DesensitizedUtils.key(origin));
break;
caseCUSTOMER:
jsonGenerator.writeString(DesensitizedUtils.desValue(origin,prefixNoMaskLen,suffixNoMaskLen,maskStr));
break;
default:
thrownewIllegalArgumentException("Unknowsensitivetypeenum"+type);
}
}else{
jsonGenerator.writeString("");
}
}else{
//logger.info("不进行脱敏处理");
jsonGenerator.writeString(origin);
}

}

@Override
publicJsonSerializercreateContextual(SerializerProviderserializerProvider,BeanPropertybeanProperty)throwsJsonMappingException{
if(beanProperty!=null){
if(Objects.equals(beanProperty.getType().getRawClass(),String.class)){
PrivacyEncryptencrypt=beanProperty.getAnnotation(PrivacyEncrypt.class);
if(encrypt==null){
encrypt=beanProperty.getContextAnnotation(PrivacyEncrypt.class);
}
if(encrypt!=null){
returnnewPrivacySerialize(encrypt.type(),encrypt.prefixNoMaskLen(),
encrypt.suffixNoMaskLen(),encrypt.maskStr());
}
}
returnserializerProvider.findValueSerializer(beanProperty.getType(),beanProperty);
}
returnserializerProvider.findNullValueSerializer(null);
}

privateListgetFieldList(Classclazz){
if(null==clazz){
returnnull;
}
ListfieldList=newArrayList<>();
//递归查找需求的字段
ClassaClass=ClassRecursionUtils.getClass(clazz,"isPrivacyKey");
Field[]declaredFields=aClass.getDeclaredFields();
for(Fieldfield:declaredFields){
if(field!=null){
//设置属性的可访问性
field.setAccessible(true);
//过滤静态
if(Modifier.isStatic(field.getModifiers())){
continue;
}
Stringname=field.getName();
//过滤非布尔类型
Classtype=field.getType();
//并且只添加isPrivacyKey
if(type.isAssignableFrom(Boolean.class)&&"isPrivacyKey".equals(name)){
fieldList.add(field);
}
}
}
returnfieldList;
}

}

递归工具类

publicclassClassRecursionUtils{
publicstaticClassgetClass(Classc,StringfieldName){
if(c!=null&&!hasField(c,fieldName)){
returngetClass(c.getSuperclass(),fieldName);
}
returnc;
}

publicstaticbooleanhasField(Classc,StringfieldName){
Field[]fields=c.getDeclaredFields();
for(Fieldf:fields){
if(fieldName.equals(f.getName())){
returntrue;
}
}
returnfalse;
}
}

现在只需要在进行实体类 封装数据时,在进行手动set即可

4 最终方案

在上述情况下可以实现 手动控制是否在某些场景下的脱敏,但是需要对原来的代码进行修改,我觉得不友好,所以采用aop的形式进行控制

项目的返回类型基本上为两种

  • 实体类作为返回
  • 分页返回

aop注解

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})//作用于方法上
public@interfacePrivacyKeyAnnotation{

/**
*是否启用序列化脱敏默认开启
*/
booleanisKey()defaulttrue;

/**
*是否为PageInfo(分页对象)
*/
booleanisPageKey()defaultfalse;
}

aop类

@Component
@Aspect
publicclassPrivacyKeyAspect{
publicstaticfinalLoggerlogger=LoggerFactory.getLogger(PrivacyKeyAspect.class);

/**
*@Description:环绕通知包含此注解的
*@param:ProceedingJoinPointjoinPoint
*@return:Object
*/
@Around(value="@annotation("aop注解地址xxxxx")")
publicObjectrepeatSub(ProceedingJoinPointjoinPoint)throwsThrowable{
returnjoinPoint.proceed();
}

/**
*@Description:后置通知
*/
@AfterReturning(value="@annotation("aop注解地址")",returning="result")
publicvoidsetPrivacyKeyType(JoinPointjoinPoint,Objectresult)throwsThrowable{
//进行注解值获取
MethodSignaturesignature=(MethodSignature)joinPoint.getSignature();
Methodmethod=signature.getMethod();
//是否开启脱敏
booleanflag=method.getDeclaredAnnotation(PrivacyKeyAnnotation.class).isKey();
//是否对分页进行脱敏
booleanstatus=method.getDeclaredAnnotation(PrivacyKeyAnnotation.class).isPageKey();
if(!status){
//进行返回值反射
ClassaClass=ClassRecursionUtils.getClass(result.getClass(),"isPrivacyKey");
if(null!=aClass){
setFieldMethod(result,flag,aClass);
}
}else{
//反射分页page
//反射list类型
Parameter[]parameters=signature.getMethod().getParameters();
//泛型名称
Stringname=parameters[0].getName();
//泛型class
Classtype=parameters[0].getType();
//包名
StringtypeName=type.getName();
PropertyDescriptor[]ps=Introspector.getBeanInfo(result.getClass(),Object.class).getPropertyDescriptors();
for(PropertyDescriptorprop:ps){
if(prop.getPropertyType().isAssignableFrom(List.class)){//List集合类型
Objectobj=result.getClass().getMethod(prop.getReadMethod().getName()).invoke(result);
if(obj!=null){
ListlistObj=(List)obj;
for(Objectnext:listObj){
ClassclassObj=Class.forName(typeName);
//获取成员变量
ClasskeyClass=ClassRecursionUtils.getClass(classObj,"isPrivacyKey");
setFieldMethod(next,flag,keyClass);
}
}

}
}
}
}

/**
*内容填充
*/
privatevoidsetFieldMethod(Objectresult,booleanflag,ClassaClass)throwsIllegalAccessException{
Field[]declaredFields=aClass.getDeclaredFields();
for(Fieldfield:declaredFields){
//设置属性的可访问性
field.setAccessible(true);
//只获取isPrivacyKey
Stringname=field.getName();
//过滤非布尔类型
Classtype=field.getType();
//并且只添加isPrivacyKey
if(type.isAssignableFrom(Boolean.class)&&"isPrivacyKey".equals(name)){
//重新写入
field.set(result,flag);
}
}
}
}

使用 在service implement类方法上写入

最后,另一种实现方式,可以参考:

https://juejin.cn/post/7242145254057410615


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • AOP
    AOP
    +关注

    关注

    0

    文章

    41

    浏览量

    11553
  • 数据权限
    +关注

    关注

    0

    文章

    5

    浏览量

    6167
  • SpringBoot
    +关注

    关注

    0

    文章

    178

    浏览量

    712

原文标题:SpringBoot 采用 JsonSerializer 和 Aop 实现可控制的数据脱敏

文章出处:【微信号:芋道源码,微信公众号:芋道源码】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    打破计量孤岛,告别能耗盲区,实现能耗可视可控

    Acrel-5000 面向机关办公建筑 / 大型公共建筑,提供集能耗监测、统计分析、空调末端控制、碳资产管理、绿色建筑上报于一体的全流程能效管控方案,实现用能可测、可视、可控、可算 核心架构
    的头像 发表于 03-18 14:52 140次阅读
    打破计量孤岛,告别能耗盲区,<b class='flag-5'>实现</b>能耗可视<b class='flag-5'>可控</b>

    IWR6843AOP毫米波传感器:工业雷达应用的理想之选

    传感器,凭借其高度集成的特性和卓越的性能,成为了众多工业应用的理想解决方案。 文件下载: iwr6843aop.pdf 1. 核心特性 1.1 集成度高 IWR6843AOP采用了天线封装(A
    的头像 发表于 02-11 15:30 295次阅读

    AWR6843AOP:汽车毫米波雷达的理想之选

    AWR6843AOP:汽车毫米波雷达的理想之选 在当今汽车电子领域,毫米波雷达技术正扮演着越来越重要的角色。它为汽车提供了精准的环境感知能力,是实现高级驾驶辅助系统(ADAS)和自动驾驶的关键技术
    的头像 发表于 02-11 15:00 263次阅读

    AWR1843AOP毫米波传感器:汽车雷达设计的理想之选

    、AWR1843AOP的特性亮点 1. 高度集成的硬件架构 AWR1843AOP采用了TI的低功耗45 - nm RFCMOS工艺,在极小的封装内实现
    的头像 发表于 02-11 14:00 293次阅读

    解锁毫米波雷达新潜力:AWR1843AOP深度解析

    魅力和应用潜力。 文件下载: awr1843aop.pdf 一、AWR1843AOP概述 AWR1843AOP是一款工作在76 - 81GHz频段的天线封装(AOP)器件,
    的头像 发表于 01-26 16:05 378次阅读

    IWR1843AOP毫米波传感器:工业应用的理想之选

    高达4 GHz的连续线性调频带宽。它采用了德州仪器的低功耗45 - nm RFCMOS工艺,在极小的外形尺寸下实现了前
    的头像 发表于 01-26 11:05 482次阅读

    IWRL6432AOP:工业雷达传感器的技术解析与应用展望

    IWRL6432AOP:工业雷达传感器的技术解析与应用展望 在工业雷达传感器领域,TI 的 IWRL6432AOP 凭借其卓越的性能和丰富的功能,成为了众多工程师关注的焦点。今天,我们就来深入剖析
    的头像 发表于 01-25 16:55 1026次阅读

    晶台可控硅光耦如何“守护”智能家电?

    在智能家居浪潮中,集可控硅与光电耦合功能于一体的可控硅光耦,通过光电隔离实现强弱电信号的精准控制,为家电设备提供多重保护屏障。▲可控硅光耦器
    的头像 发表于 01-12 11:23 493次阅读
    晶台<b class='flag-5'>可控</b>硅光耦如何“守护”智能家电?

    奥特可控硅光耦:赋能灯光控制的核心器件与选型策略

    在现代灯光控制系统中,安全隔离、精准调光与稳定运行是核心诉求。可控硅光耦作为实现“弱电控制强电”的关键器件,凭借其电气隔离特性、无触点开关优势,广泛应用于智能家居照明、工业照明、商业调
    的头像 发表于 01-06 16:52 1075次阅读
    奥特<b class='flag-5'>可控</b>硅光耦:赋能灯光<b class='flag-5'>控制</b>的核心器件与选型策略

    可控硅光耦的核心应用场景及选型指南

    在现代家居家用电器中,可控硅光耦(Thyristooptocoupler)凭借着其独特的交流输出控制、电器隔离、无触点的特点,成为了实现安全、高效、高功率控制的关键元件。
    的头像 发表于 12-09 16:58 1710次阅读
    <b class='flag-5'>可控</b>硅光耦的核心应用场景及选型指南

    如何使用SpringBoot、Vue2.0、MySQL开发一套云诊所系统?

    SpringBoot是Java领域非常流行的快速开发框架,提供了丰富的生态和自动化配置,适合构建微服务和单体应用。 它可以很好地处理业务逻辑、数据持久化、安全性(Spring Security)和API接口
    的头像 发表于 11-27 16:02 403次阅读
    如何使用<b class='flag-5'>SpringBoot</b>、Vue2.0、MySQL开发一套云诊所系统?

    可控硅光耦在工业电机控制中的精准调速应用

    在工业自动化领域,可控硅光耦凭借其电气隔离与信号精准传递特性,成为电机调速系统的核心元件。晶台光电推出的可控硅光耦,通过光耦合技术实现控制电路与高压主回路的完全隔离,有效避免电磁干扰对
    的头像 发表于 10-17 08:56 2267次阅读
    <b class='flag-5'>可控</b>硅光耦在工业电机<b class='flag-5'>控制</b>中的精准调速应用

    ‌Texas Instruments AWR1843AOP汽车雷达传感器数据手册摘要

    Texas Instruments AWR1843AOP汽车雷达传感器是封装天线器件,在76GHz至81GHz频段内工作。AWR1843AOP采用TI’的低功耗45nm RFCMOS工艺,在微型外形中
    的头像 发表于 09-26 14:52 1087次阅读
    ‌Texas Instruments AWR1843<b class='flag-5'>AOP</b>汽车雷达传感器<b class='flag-5'>数据</b>手册摘要

    SAP 数据脱敏工具:SNP TDO如何满足新颁敏感信息政策要求

    面对我国新颁《数据安全法》《个保法》敏感信息政策,本篇文章将详细解答企业数据合规三大刚需:国家机密防护、商业数据保护、个人隐私脱敏
    的头像 发表于 08-19 09:49 548次阅读

    可控硅光耦怎么使用?

    自动控制系统中,可作为大功率驱动器件,实现用小功率控件控制大功率设备。它在交直流电机调速系统、调功系统及随动系统中得到了广泛的应用。而可控硅光耦(SCR光耦)凭借其高隔
    的头像 发表于 07-15 10:12 2055次阅读
    <b class='flag-5'>可控</b>硅光耦怎么使用?