三星將進軍電動車市場?已申請多項相關專利

據「華爾街日報」(WSJ)報導,雖然三星集團對WSJ稱,沒有進軍電動車市場的計畫。但三星電子(Samsung Electronics)今年在美國和韓國申請的專利,涵蓋了可用在電動車的零件和技術,這些文件透露出這個財團可能在動擴大營收來源的腦筋。

根據美國專利商標局(U.S. Patent & Trademark Office)和韓國智慧財產權局訊息服務局(Korea Intellectual Property Rights Information Service)公布的專利申請文件,三星遞交的申請文件是電動車會使用的汽車零件製作新技術。三星申請的技術專利包含輪胎、引擎及分享資訊給汽車和駕駛者的車上電子產品。

電動車目前在全球市場的人氣還不高,但這為三星提供了將技術實力發揮在智慧型手機、電視和記憶體以外產品的機會,三星在競爭激烈的電視和行動裝置市場動能已經放慢。

大和證券分析指出,一旦世界進入電動車時代,車廠和電子企業的界線將日益模糊;等到電動車日益普及,三星可輕鬆加入獲利。8月公佈的專利案顯示,三星有意結合汽車和醫療科技,依照駕駛的身體情況,讓車輛接手控制。

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

※想知道最厲害的網頁設計公司"嚨底家"!

※幫你省時又省力,新北清潔一流服務好口碑

※別再煩惱如何寫文案,掌握八大原則!

※產品缺大量曝光嗎?你需要的是一流包裝設計!

HEV(混合動力車輛)

混合動力車輛(Hybrid electric vehicle, HEV)),是使用兩種或以上能源的車輛,所使用的動力來源有:內燃機、電動機、電池、氫氣、燃料電池等的技術。

多數油電混合動力車使用汽油,雖然消耗汽油較少,但是加速表現卻較佳,被視為比普通由內燃引擎發動車輛較為環保的選擇。近年有的可以從輸電網絡上向內部電池充電,叫插電式混合動力汽車(Plug-in hybrid, PHEV)。

原理

絕大多數的混合動力車的推動裝置不外乎內燃機或電動機,若當中有使用電力推動電動機作為其中一種推動裝置者即可以用電池進行再生制動,把能量回收,以節省能源,現在較普遍使用的油電混合動力車就屬於這一類。油電混合動力車或柴電動力車的推動裝置可以是同時擁有電動機及內燃機引擎,也有只使用電動機的設計。

分類方式

以動力來源劃分:
1 油電混合動力 及柴電混合動力
2 燃料電池和電池混合車
3 液壓動力混合系統
4 多重燃料混合動力系統
5 人力混合動力系統

依程度分類(degree of hybridization):
1 輕度混合動力
2 中度混合動力
3 重度混合動力
4 插電式混合動力(PHEV)

依傳動配置分類(drive train structure/power train configurations):
1 並聯式油電混合系統
2 串聯混合動力系統
3 混聯式混合動力系統(動力整合/分配式混合動力系統)

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

新北清潔公司,居家、辦公、裝潢細清專業服務

※別再煩惱如何寫文案,掌握八大原則!

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

※超省錢租車方案

※教你寫出一流的銷售文案?

網頁設計最專業,超強功能平台可客製化

一起玩轉微服務(10)——spring boot介紹

對於Spring,相信大家都非常熟悉,從出現開始,一直是企業級開發的主流。但是隨着軟件的發展和應用開發的不斷演化,它的一些缺點也逐漸胡暴露了出來,下面,我們就一起看一下Spring的發展歷程並且認識一下Spring Boot。

由來

在Spring 1.x的時候,所有的配置都通過XML,隨着項目的擴大,需要頻繁的在java和XML之間切換。 在Spring 2.x的時候,已經開始逐步替換掉XML配置。在Spring 3.x的時候,已經開始提供java的配置方式,在4.x的時候,已經全部推薦使用java配置的方式。隨着動態語言的流行,java的開發顯得格外的繁瑣,體現在配置的複雜、開發效率低下、部署以及與第三方的集成繁雜,這個時候Spring Boot應運而生。

 

 

 Spring Boot 是由 Pivotal 團隊提供的全新框架,其設計目的是用來簡化新 Spring 應用的初始搭建以及開發過程。該框架使用了特定的方式來進行配置,從而使開發人員不再需要定義樣板化的配置。簡化了基於 Spring 的應用開發,通過少量的代碼就能創建一個獨立的、產品級別的 Spring 應用。Spring Boot 為 Spring 平台及第三方庫提供開箱即用的設置,減少與第三方庫集成的複雜度。 Spring Boot 的核心思想就是約定大於配置,多數 Spring Boot 應用只需要很少的 Spring 配置。採用 Spring Boot 可以大大的簡化你的開發模式,所有你想集成的常用框架,它都有對應的組件支持。

 

特性

1.方便地創建獨立的Spring應用,為基於Spring的開發提供更快的入門體驗。2.內置嵌入tomcat,無需生成war文件。3.簡化maven配置。4.自動配置Spring,更快、更方便的與第三方應用整合,比如消息隊列、緩存等在企業級開發中常用的組件。5.提供大型項目中的非功能特性。如:指標、安全、健康檢查及外部配置。6.開箱即用,無需代碼生成,也無需XML配置,同時也能夠通過修改默認值來滿足待定的需求。

四大神器

自動配置

Spring Boot 的自動配置功能可基於類路徑檢測自動為運行中的應用配置依賴關係,不需要提供額外的XML配置。

Starters

Spring Boot 可提供一系列稱為 POM Starters 的精細依賴關係。Spring Boot 熟知如何配置這些依賴關係,同時讓組織能夠擴展 Spring Boot 來配置自定義的依賴關係。

Actuator

Actuator 可提供運行狀況檢查和指標等生產就緒型功能。這些功能通過 Spring Boot 應用內的 REST 終端提供。只需要簡單的配置就可以實現強大的監控和檢查。

開發工具

這些工具旨在縮短開發和測試周期,其中包括一個可在資源變更時觸發瀏覽器刷新的嵌入式 LiveReload 服務器。這些工具還提供了應用自動重啟功能,只要類路徑上的文件發生更改,該功能更即可啟動。重啟技術使用兩種類加載器。未更改的分類(例如來自第三方 JAR 的類)被加載到基礎類加載器,而開發中的分類則被加載到重啟類加載器。當應用重啟時,重啟類加載器會被丟棄,同時創建一個新的類加載器。這種方法意味着應用重啟的速度通常要比“冷啟動”的速度快得多,因為基礎類加載器已準備就緒且已填充完畢。從而快速實現應用的熱部署,對於簡單的修改這種場景能夠非常有效的提高效率。

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※為什麼 USB CONNECTOR 是電子產業重要的元件?

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

※台北網頁設計公司全省服務真心推薦

※想知道最厲害的網頁設計公司"嚨底家"!

新北清潔公司,居家、辦公、裝潢細清專業服務

※推薦評價好的iphone維修中心

架構設計 | 高併發流量削峰,共享資源加鎖機制

本文源碼:GitHub·點這裏 || GitEE·點這裏

一、高併發簡介

在互聯網的業務架構中,高併發是最難處理的業務之一,常見的使用場景:秒殺,搶購,訂票系統;高併發的流程中需要處理的複雜問題非常多,主要涉及下面幾個方面:

  • 流量管理,逐級承接削峰;
  • 網關控制,路由請求,接口熔斷;
  • 併發控制機制,資源加鎖;
  • 分佈式架構,隔離服務和數據庫;

高併發業務核心還是流量控制,控制流量下沉速度,或者控制承接流量的容器大小,多餘的直接溢出,這是相對複雜的流程。其次就是多線程併發下訪問共享資源,該流程需要加鎖機制,避免數據寫出現錯亂情況。

二、秒殺場景

1、預搶購業務

活動未正式開始,先進行活動預約,先把一部分流量收集和控制起來,在真正秒殺的時間點,很多數據可能都已經預處理好了,可以很大程度上削減系統的壓力。有了一定預約流量還可以提前對庫存系統做好準備,一舉兩得。

場景:活動預約,定金預約,高鐵搶票預購。

2、分批搶購

分批搶購和搶購的場景實現的機制是一致的,只是在流量上緩解了很多壓力,秒殺10W件庫存和秒殺100件庫存系統的抗壓不是一個級別。如果秒殺10W件庫存,系統至少承擔多於10W幾倍的流量衝擊,秒殺100件庫存,體系可能承擔幾百或者上千的流量就結束了。下面流量削峰會詳解這裏的策略機制。

場景:分時段多場次搶購,高鐵票分批放出。

3、實時秒殺

最有難度的場景就是準點實時的秒殺活動,假如10點整準時搶1W件商品,在這個時間點前後會湧入高併發的流量,刷新頁面,或者請求搶購的接口,這樣的場景處理起來是最複雜的。

  • 首先系統要承接住流量的湧入;
  • 頁面的不斷刷新要實時加載;
  • 高併發請求的流量控制加鎖等;
  • 服務隔離和數據庫設計的系統保護;

場景:618準點搶購,雙11準點秒殺,電商促銷秒殺。

三、流量削峰

1、Nginx代理

Nginx是一個高性能的HTTP和反向代理web服務器,經常用在集群服務中做統一代理層和負載均衡策略,也可以作為一層流量控制層,提供兩種限流方式,一是控制速率,二是控制併發連接數。

基於漏桶算法,提供限制請求處理速率能力;限制IP的訪問頻率,流量突然增大時,超出的請求將被拒絕;還可以限制併發連接數。

高併發的秒殺場景下,經過Nginx層的各種限制策略,可以控制流量在一個相對穩定的狀態。

2、CDN節點

CDN靜態文件的代理節點,秒殺場景的服務有這樣一個操作特點,活動倒計時開始之前,大量的用戶會不斷的刷新頁面,這時候靜態頁面可以交給CDN層面代理,分擔數據服務接口的壓力。

CDN層面也可以做一層限流,在頁面內置一層策略,假設有10W用戶點擊搶購,可以只放行1W的流量,其他的直接提示活動結束即可,這也是常用的手段之一。

話外之意:平時參与的搶購活動,可能你的請求根本沒有到達數據接口層面,就極速響應商品已搶完,自行意會吧。

3、網關控制

網關層面處理服務接口路由,一些校驗之外,最主要的是可以集成一些策略進入網關,比如經過上述層層的流量控制之後,請求已經接近核心的數據接口,這時在網關層面內置一些策略控制:如果活動是想激活老用戶,網關層面快速判斷用戶屬性,老用戶會放行請求;如果活動的目的是拉新,則放行更多的新用戶。

經過這些層面的控制,剩下的流量已經不多了,後續才真正開始執行搶購的數據操作。

話外之意:如果有10W人參加搶購活動,真正下沉到底層的搶購流量可能就1W,甚至更少,在分散到集群服務中處理。

4、併發熔斷

在分佈式服務的接口中,還有最精細的一層控制,對於一個接口在單位之間內控制請求處理的數量,這個基於接口的響應時間綜合考慮,響應越快,單位時間內的併發量就越高,這裏邏輯不難理解。

言外之意:流量經過層層控制,數據接口層面分擔的壓力已經不大,這時候就是面對秒殺業務中的加鎖問題了。

四、分佈式加鎖

1、悲觀鎖

機制描述

所有請求的線程必須在獲取鎖之後,才能執行數據庫操作,並且基於序列化的模式,沒有獲取鎖的線程處於等待狀態,並且設定重試機制,在單位時間后再次嘗試獲取鎖,或者直接返回。

過程圖解

Redis基礎命令

SETNX:加鎖的思路是,如果key不存在,將key設置為value如果key已存在,則 SETNX 不做任何動作。並且可以給key設置過期時間,過期后其他線程可以繼續嘗試鎖獲取機制。

藉助Redis的該命令模擬鎖的獲取動作。

代碼實現

這裏基於Redis實現的鎖獲取和釋放機制。

import org.springframework.stereotype.Component;
import redis.clients.jedis.Jedis;
import javax.annotation.Resource;
@Component
public class RedisLock {

    @Resource
    private Jedis jedis ;

    /**
     * 獲取鎖
     */
    public boolean getLock (String key,String value,long expire){
        try {
            String result = jedis.set( key, value, "nx", "ex", expire);
            return result != null;
        } catch (Exception e){
            e.printStackTrace();
        }finally {
            if (jedis != null) jedis.close();
        }
        return false ;
    }

    /**
     * 釋放鎖
     */
    public boolean unLock (String key){
        try {
            Long result = jedis.del(key);
            return result > 0 ;
        } catch (Exception e){
            e.printStackTrace();
        }finally {
            if (jedis != null) jedis.close();
        }
        return false ;
    }
}

這裏基於Jedis的API實現,這裏提供一份配置文件。

@Configuration
public class RedisConfig {

    @Bean
    public JedisPoolConfig jedisPoolConfig (){
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig() ;
        jedisPoolConfig.setMaxIdle(8);
        jedisPoolConfig.setMaxTotal(20);
        return jedisPoolConfig ;
    }

    @Bean
    public JedisPool jedisPool (@Autowired JedisPoolConfig jedisPoolConfig){
        return new JedisPool(jedisPoolConfig,"127.0.0.1",6379) ;
    }

    @Bean
    public Jedis jedis (@Autowired JedisPool jedisPool){
        return jedisPool.getResource() ;
    }
}

問題描述

在實際的系統運行期間可能出現如下情況:線程01獲取鎖之後,進程被掛起,後續該執行的沒有執行,鎖失效后,線程02又獲取鎖,在數據庫更新后,線程01恢復,此時在持有鎖之後的狀態,繼續執行后就會容易導致數據錯亂問題。

這時候就需要引入鎖版本概念的,假設線程01獲取鎖版本1,如果沒有執行,線程02獲取鎖版本2,執行之後,通過鎖版本的比較,線程01的鎖版本過低,數據更新就會失敗。

CREATE TABLE `dl_data_lock` (
	`id` INT (11) NOT NULL AUTO_INCREMENT COMMENT '主鍵ID',
	`inventory` INT (11) DEFAULT '0' COMMENT '庫存量',
	`lock_value` INT (11) NOT NULL DEFAULT '0' COMMENT '鎖版本',
	PRIMARY KEY (`id`)
) ENGINE = INNODB DEFAULT CHARSET = utf8 COMMENT = '鎖機製表';

說明:lock_value就是記錄鎖版本,作為控制數據更新的條件。

<update id="updateByLock">
    UPDATE dl_data_lock SET inventory=inventory-1,lock_value=#{lockVersion}
    WHERE id=#{id} AND lock_value &lt;#{lockVersion}
</update>

說明:這裏的更新操作,不但要求線程獲取鎖,還會判斷線程鎖的版本不能低於當前更新記錄中的最新鎖版本。

2、樂觀鎖

機制描述

樂觀鎖大多是基於數據記錄來控制,在更新數據庫的時候,基於前置的查詢條件判斷,如果查詢出來的數據沒有被修改,則更新操作成功,如果前置的查詢結果作為更新的條件不成立,則數據寫失敗。

過程圖解

代碼實現

業務流程,先查詢要更新的記錄,然後把讀取的列,作為更新條件。

@Override
public Boolean updateByInventory(Integer id) {
    DataLockEntity dataLockEntity = dataLockMapper.getById(id);
    if (dataLockEntity != null){
        return dataLockMapper.updateByInventory(id,dataLockEntity.getInventory())>0 ;
    }
    return false ;
}

例如如果要把庫存更新,就把讀取的庫存數據作為更新條件,如果讀取庫存是100,在更新的時候庫存變了,則更新條件自然不能成立。

<update id="updateByInventory">
    UPDATE dl_data_lock SET inventory=inventory-1 WHERE id=#{id} AND inventory=#{inventory}
</update>

五、分佈式服務

1、服務保護

在處理高併發的秒殺場景時,經常出現服務掛掉場景,常見某些APP的營銷頁面,出現活動火爆頁面丟失的提示情況,但是不影響整體應用的運行,這就是服務的隔離和保護機制。

基於分佈式的服務結構可以把高併發的業務服務獨立出來,不會因為秒殺服務掛掉影響整體的服務,導致服務雪崩的場景。

2、數據庫保護

數據庫保護和服務保護是相輔相成的,分佈式服務架構下,服務和數據庫是對應的,理論上秒殺服務對應的就是秒殺數據庫,不會因為秒殺庫掛掉,導致整個數據庫宕機。

六、源代碼地址

GitHub·地址
https://github.com/cicadasmile/data-manage-parent
GitEE·地址
https://gitee.com/cicadasmile/data-manage-parent

推薦閱讀:《架構設計系列》,蘿蔔青菜,各有所需

序號 標題
00 架構設計:單服務.集群.分佈式,基本區別和聯繫
01 架構設計:分佈式業務系統中,全局ID生成策略
02 架構設計:分佈式系統調度,Zookeeper集群化管理
03 架構設計:接口冪等性原則,防重複提交Token管理
04 架構設計:緩存管理模式,監控和內存回收策略
05 架構設計:異步處理流程,多種實現模式詳解

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

※想知道購買電動車哪裡補助最多?台中電動車補助資訊懶人包彙整

南投搬家公司費用,距離,噸數怎麼算?達人教你簡易估價知識!

※教你寫出一流的銷售文案?

※超省錢租車方案

深入淺出PyTorch(算子篇)

Tensor

自從張量(Tensor)計算這個概念出現后,神經網絡的算法就可以看作是一系列的張量計算。所謂的張量,它原本是個數學概念,表示各種向量或者數值之間的關係。PyTorch的張量(torch.Tensor)表示的是N維矩陣與一維數組的關係。

torch.Tensor的使用方法和numpy很相似(https://pytorch.org/…tensor-tutorial-py),兩者唯一的區別在於torch.Tensor可以使用GPU來計算,這就比用CPU的numpy要快很多。

張量計算的種類有很多,比如加法、乘法、矩陣相乘、矩陣轉置等,這些計算被稱為算子(Operator),它們是PyTorch的核心組件。

算子的backend一般是C/C++的拓展程序,PyTorch的backend是稱為”ATen”的C/C++庫,ATen是”A Tensor”的縮寫。

Operator

PyTorch所有的Operator都定義在Declarations.cwrap和native_functions.yaml這兩個文件中,前者定義了從Torch那繼承來的legacy operator(aten/src/TH),後者定義的是native operator,是PyTorch的operator。

相比於用C++開發的native code,legacy code是在PyTorch編譯時由gen.py根據Declarations.cwrap的內容動態生成的。因此,如果你想要trace這些code,需要先編譯PyTorch。

legacy code的開發要比native code複雜得多。如果可以的話,建議你盡量避開它們。

MatMul

本文會以矩陣相乘–torch.matmul()為例來分析PyTorch算子的工作流程。

我在深入淺出全連接層(fully connected layer)中有講在GPU層面是如何進行矩陣相乘的。Nvidia、AMD等公司提供了優化好的線性代數計算庫–cuBLAS/rocBLAS/openBLAS,PyTorch只需要調用它們的API即可。

Figure 1是torch.matmul()在ATen中的function flow。可以看到,這個flow可不短,這主要是因為不同類型的tensor(2d or Nd, batched gemm or not,with or without bias,cuda or cpu)的操作也不盡相同。

at::matmul()主要負責將Tensor轉換成cuBLAS需要的格式。前面說過,Tensor可以是N維矩陣,如果tensor A是3d矩陣,tensor B是2d矩陣,就需要先將3d轉成2d;如果它們都是>=3d的矩陣,就要考慮batched matmul的情況;如果bias=True,後續就應該交給at::addmm()來處理;總之,matmul要考慮的事情比想象中要多。

除此之外,不同的dtype、device和layout需要調用不同的操作函數,這部分工作交由c10::dispatcher來完成。

Dispatcher

dispatcher主要用於動態調用dtype、device以及layout等方法函數。用過numpy的都知道,np.array()的數據類型有:float32, float16,int8,int32,…. 如果你了解C++就會知道,這類程序最適合用模板(template)來實現。

很遺憾,由於ATen有一部分operator是用C語言寫的(從Torch繼承過來),不支持模板功能,因此,就需要dispatcher這樣的動態調度器。

類似地,PyTorch的tensor不僅可以運行在GPU上,還可以跑在CPU、mkldnn和xla等設備,Figure 1中的dispatcher4就根據tensor的device調用了mm的GPU實現。

layout是指tensor中元素的排布。一般來說,矩陣的排布都是緊湊型的,也就是strided layout。而那些有着大量0的稀疏矩陣,相應地就是sparse layout。

Figure 2是strided layout的演示實例,這裏創建了一個2行2列的矩陣a,它的數據實際存放在一維數組(a.storage)里,2行2列只是這個數組的視圖。

stride充當了從數組到視圖的橋樑,比如,要打印第2行第2列的元素時,可以通過公式:\(1 * stride(0) + 1 * stride(1)\)來計算該元素在數組中的索引。

除了dtype、device、layout之外,dispatcher還可以用來調用legacy operator。比如說addmm這個operator,它的GPU實現就是通過dispatcher來跳轉到legacy::cuda::_th_addmm。

END

到此,就完成了對PyTorch算子的學習。如果你要學習其他算子,可以先從aten/src/ATen/native目錄的相關函數入手,從native_functions.yaml中找到dispatch目標函數,詳情可以參考Figure 1。

更多精彩文章,歡迎掃碼關注下方的公眾號, 並訪問我的簡書博客:https://www.jianshu.com/u/c0fe8671254e

歡迎轉發至朋友圈,工作號轉載請後台留言申請授權~

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

※Google地圖已可更新顯示潭子電動車充電站設置地點!!

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※別再煩惱如何寫文案,掌握八大原則!

網頁設計最專業,超強功能平台可客製化

MyBatis入門學習-連接oracle實現CURD基本操作

目錄

  • 前言
  • 導入oracle庫
  • 配置
    • 環境配置
    • 配置引用
    • 配置映射
  • 查詢
    • 單條件查詢
    • 多條件查詢
      • 通過類字段傳遞參數
      • 通過Map接口傳參
      • Param註解
  • 插入
  • 更新
  • 刪除
  • 字段映射
  • 參考文獻

前言

本篇記錄使用mybatis連接oracle數據庫實現基本的CURD操作。

導入oracle庫

由於oracle收費, 因此maven沒有oracle庫包,需要我們自己導入,可以手工導入外部包,也可以將oracle的jar導入到maven庫種。具體導入步驟可以查看Maven添加Oracle的依賴及驅動

導入mybatis庫包,我本地使用的是3.5.5版本。最後的配置如下所示


<dependency>
  <groupId>org.mybatis</groupId>
  <artifactId>mybatis</artifactId>
  <version>3.5.5</version>
</dependency>

<dependency>
  <groupId>com.oracle.jdbc</groupId>
  <artifactId>ojdbc6</artifactId>
  <version>11.2.0.1.0</version>
</dependency>

配置

準備mybatis的配置,在resources目錄下新建一個mybatis-config.xml文件,配置如下

 <?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<!-- 根標籤 -->
<configuration>
    <properties>
        <property name="driver" value="oracle.jdbc.driver.OracleDriver" />
        <property name="url" value="jdbc:oracle:thin:@10.60.45.239:1521:devdb" />
        <property name="username" value="fgmain10001" />
        <property name="password" value="test1" />
    </properties>

    <!-- 環境,可以配置多個,default:指定採用哪個環境 -->
    <environments default="test">
        <!-- id:唯一標識 -->
        <environment id="test">
            <!-- 事務管理器,JDBC類型的事務管理器 -->
            <transactionManager type="JDBC" />
            <!-- 數據源,池類型的數據源 -->
            <dataSource type="POOLED">
                <property name="driver" value="oracle.jdbc.driver.OracleDriver" />
                <property name="url" value="jdbc:oracle:thin:@10.60.45.239:1521:devdb" />
                <property name="username" value="fgmain10001" />
                <property name="password" value="test1" />
            </dataSource>
        </environment>
        <environment id="development">
            <!-- 事務管理器,JDBC類型的事務管理器 -->
            <transactionManager type="JDBC" />
            <!-- 數據源,池類型的數據源 -->
            <dataSource type="POOLED">
                <property name="driver" value="${driver}" /> <!-- 配置了properties,所以可以直接引用 -->
                <property name="url" value="${url}" />
                <property name="username" value="${username}" />
                <property name="password" value="${password}" />
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="singleTransMapper.xml" />
    </mappers>
</configuration>

環境配置

 <environment id="test">
      <!-- 事務管理器,JDBC類型的事務管理器 -->
      <transactionManager type="JDBC" />
      <!-- 數據源,池類型的數據源 -->
      <dataSource type="POOLED">
          <property name="driver" value="oracle.jdbc.driver.OracleDriver" />
          <property name="url" value="jdbc:oracle:thin:@10.60.45.239:1521:devdb" />
          <property name="username" value="fgmain10001" />
          <property name="password" value="test1" />
      </dataSource>
  </environment>

其中environments可以配置多個環境的oracle數據源。

id是環境變量的編號,在<environments>default中可以設置當前的環境值。
dataSource中設置數據源。類型有3種。包括:POOLED池化,UNPOOLED非池化和JNDI從其他配置元加載。
driver配置的類名,oracle填寫oracle.jdbc.driver.OracleDriver
url為配置的數據源,使用239測試庫jdbc:oracle:thin:@10.60.45.239:1521:devdb
username是用戶名。
password是密碼。

配置引用

在value中可以填寫如${變量名}的配置引用,通過在properties/propertie添加對應的實際的配置值。

<configuration>
    <properties>
        <property name="driver" value="oracle.jdbc.driver.OracleDriver" />
    </properties>
    
    <environments default="test">
        ...
        <environment id="test">
            ...
            <dataSource type="POOLED">
                <property name="driver" value="${driver}" /> <!-- 配置了properties,所以可以直接引用 -->
                ...
            </dataSource>
        </environment>
    </environments>
</configuration>

配置映射

配置好數據源后,需要添加對應的表映射,映射包括CRUD對應的SQL語句以及與類之間的映射關係。


<configuration>
  ...
    <mappers>
        <mapper resource="singleTransMapper.xml" />
    </mappers>
</configuration>

在resources目錄下新建一個singleTransMapper.xml文件,MyBatis會將singleTransMapper.xml映射到對應的類

除了resources以外MyBatis還支持classurlpackage共四種配置

class可以配置具體類名,如com.mybatistest.DAO.SingleTransMapper
url可以配置完整的文件路徑,如file:///var/mappers/PostMapper.xml
package可以配置package名稱,註冊所有接口。

查詢


public class SingletransDTO {

    public String EnterpriseNum;

    public String TransNo;

    public String CommandCode;

    public int State;
}

單條件查詢

增加一個查詢單筆的語句,通過輸入流水號,返回查詢到的單筆信息。

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="DAO.SingleTransMapper">
    <select id="selectSingle" parameterType="String" resultType="DTO.SingletransDTO">
    select * from se_singletrans where transno = #{transno}
  </select>
</mapper>

namespace需要對應到java中的類,參數和返回類型也需要一致。

在mapper節點下添加select表示select語句
parameterType為輸入的參數
resultType為返回的類型,返回類型需要對應java中的類


public interface SingleTransMapper {
    SingletransDTO selectSingle(String transNo);
}


String resource = "mybatis-config.xml";
//加載資源
InputStream inputStream = Resources.getResourceAsStream(resource);
//創建session
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
try (SqlSession session = sqlSessionFactory.openSession()) {
  //獲取單筆映射對象
    SingleTransMapper mapper = session.getMapper(SingleTransMapper.class);
    //根據流水號查詢
    SingletransDTO blog = mapper.selectSingle("642EHDCS899XKF8P");

    if(blog != null) {
        System.out.println(blog.ENTERPRISENUM);
        System.out.println(blog.TRANSNO);
        System.out.println(blog.COMMANDCODE);
    }else{
        System.out.println("not found");
    }

}catch (Exception exception)
{
    System.out.println(exception.getMessage());
}

多條件查詢

通過類字段傳遞參數

添加一個查詢配置selectSingleByParam

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="DAO.SingleTransMapper">
   
   ...
    <select id="selectSingleByClass" resultType="DTO.SingletransDTO">
    select * from se_singletrans where transno = #{TransNo} and commandCode= #{CommandCode}
  </select>
</mapper>

對應的映射類添加方法對應的方法,MyBatis可以通過反射將類的字段映射到SQL的參數,需要注意的是類的字段名和sql中配置的大小寫需要一致。


public interface SingleTransMapper {
  ...
  SingletransDTO selectSingleByClass(SingleCondition singleCondition);
}
public class SingleCondition {
    /**
     * 流水號
     */
    public String TransNo;

    /**
     * 指令類型
     */
    public String CommandCode;

    public SingleCondition(String transNo, String commandCode)
    {
        TransNo = transNo;
        CommandCode = commandCode;
    }
}

調用構造函數類的多條件查詢方案

...
SingleTransMapper mapper = session.getMapper(SingleTransMapper.class);
SingletransDTO blog = mapper.selectSingleByClass(new SingleCondition( "642EHDCS899XKF8P","10009"));

通過Map接口傳參

另一種方案可以通過傳入HashMap,MayBatis會根據key自動映射到對應的參數。
下面實現通過流水號和指令類型查詢。
添加一個查詢配置selectSingleByMultCondition

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="DAO.SingleTransMapper">
    ...
    <select id="selectSingleByMultCondition" resultType="DTO.SingletransDTO">
    select * from se_singletrans where transno = #{transNo} and commandCode= #{commandCode}
  </select>
</mapper>

添加對應的方法,傳入參數為HashMap<String,Object> param

public interface SingleTransMapper {
  ...
    SingletransDTO selectSingleByMultCondition(HashMap<String,Object> param);
}

修改調用新的多條件查詢方法

...
//獲取單筆映射對象
SingleTransMapper mapper = session.getMapper(SingleTransMapper.class);
//根據流水號查詢
HashMap<String,Object> param = new HashMap<String,Object>();
param.put("transNo","642EHDCS899XKF8P");
param.put("commandCode","10009");
SingletransDTO blog = mapper.selectSingle2(param);
...

需要注意的是,由於HashMap的key是不區分大小寫的,因此需要和配置文件sql的參數大小寫一致。

Param註解

通過類參數和Map進行多條件查詢都需要創建額外的對象,另一種比較好的方式可以通過在方法參數上添加Param註解的方式配置方法參數和SQL參數的映射關係。

添加一個查詢配置selectSingleByParam

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="DAO.SingleTransMapper">
   
   ...
    <select id="selectSingleByParam" resultType="DTO.SingletransDTO">
    select * from se_singletrans where transno = #{param1} and commandCode= #{param2}
  </select>
</mapper>

對應的映射類添加方法對應的方法,這樣MyBatis就知道參數映射規則,就會自動映射,需要注意的數參數和sql中配置的大小寫也需要一致。


public interface SingleTransMapper {
    SingletransDTO selectSingle(String transNo);
    SingletransDTO selectSingleByMultCondition(HashMap<String,Object> param);
    SingletransDTO selectSingleByParam(@Param("param1")String transNo, @Param("param2") String commandCode);
}

調用註解傳參方法

...
//獲取單筆映射對象
SingleTransMapper mapper = session.getMapper(SingleTransMapper.class);
SingletransDTO blog = mapper.selectSingleByParam("642EHDCS899XKF8P","10009");
...

插入

在mapper下添加insert表示插入的sql映射。

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="DAO.SingleTransMapper">
  
  ...
  <insert id="insert" parameterType="DTO.SingletransDTO">
    insert into se_singletrans(ENTERPRISENUM,TRANSNO,COMMANDCODE,STATE) values(#{EnterpriseNum},#{TransNo},#{CommandCode},#{State})
  </insert>
</mapper>

添加類對應的insert方法


public interface SingleTransMapper {

    ...
    int insert(SingletransDTO singletransDTO);
}

SqlSession默認會開啟事務,在insert完成后需要調用SqlSessioncommit()方法提交事務。


try (SqlSession session = sqlSessionFactory.openSession()) {
    SingleTransMapper mapper = session.getMapper(SingleTransMapper.class);
    SingletransDTO singletransDTO = new     SingletransDTO();
    singletransDTO.EnterpriseNum  = "QT330001";
    singletransDTO.TransNo = "MYBATIS.INSERT";
    singletransDTO.CommandCode = "10009";
    int count = mapper.insert(singletransDTO);
    session.commit();
    System.out.println("insert result:" +count);
}catch (Exception exception)
{
    System.out.println(exception.getMessage());
}

我們也可以調用SqlSession openSession(boolean autoCommit)傳入參數,自動提交。

更新

在mapper下添加update節點表示插入,插入時可以對插入的字段設置條件,達成某條件是該字段才需要更新。

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="DAO.SingleTransMapper">
  
  ...
   <update id="update" parameterType="DTO.SingletransDTO">
    update se_singletrans
    <set>
        <if test="State != null and State!=''"></if>
        STATE=#{State}
    </set>
    where transno = #{TransNo} and commandCode= #{CommandCode}
  </update>
</mapper>

添加類對應的update方法


public interface SingleTransMapper {

    ...
    int update(SingletransDTO singletransDTO);
}

SqlSession默認會開啟事務,和insert一樣,在update完成后需要調用SqlSessioncommit()方法提交事務。


try (SqlSession session = sqlSessionFactory.openSession()) {
    SingleTransMapper mapper = session.getMapper(SingleTransMapper.class);
    SingletransDTO singletransDTO = new SingletransDTO();
    singletransDTO.EnterpriseNum = "QT330001";
    singletransDTO.TransNo = "MYBATIS.INSERT";
    singletransDTO.CommandCode = "10009";
    singletransDTO.State = 2;
    int count = mapper.update(singletransDTO);
    session.commit();
    System.out.println("update result:" +count);
}catch (Exception exception)
{
    System.out.println(exception.getMessage());
}

刪除

在mapper下添加delete節點表示刪除。

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="DAO.SingleTransMapper">
  
  ...
   
  <delete id="delete">
    delete from se_singletrans where transno = #{TransNo} and commandCode= #{CommandCode}
  </delete>
</mapper>

添加類對應的delete方法,可以通過參數註解的方式指定參數。


public interface SingleTransMapper {

    ...
    int delete(@Param("TransNo")String transNo, @Param("CommandCode") String commandCode);
}

SqlSession默認會開啟事務,在delete完成后需要調用SqlSessioncommit()方法提交事務。


try (SqlSession session = sqlSessionFactory.openSession()) {
    SingleTransMapper mapper = session.getMapper(SingleTransMapper.class);
    int count = mapper.delete("MYBATIS.INSERT","10009");
    session.commit();
    System.out.println("delete result:" +count);
}catch (Exception exception)
{
    System.out.println(exception.getMessage());
}

字段映射

若字段名和數據庫的字段名不一致,可以通過配置進行映射。添加resultMap節點,配置類字段和數據庫字段的映射關係,若沒有配置的字段,則根據默認MyBatis的映射關係處理,即字段名一樣的自動映射,MyBatis會嘗試進行類型轉換,若轉換異常,則可能拋錯。我們也可以通過typeHandler自定義自己的類型處理器。

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="DAO.SingleTransMapper">

  <resultMap id="singleResultMap" type="DTO.SingletransDTO">
    <result property="TransNo"  column="transNo" />
    <result property="CommandCode" column="commandCode"/>
    <result property="SpecialProperty" typeHandler="CustomTypeHandle" column="SpecialColumn"/>
  </resultMap>
  <select id="selectSingleToReusltMap" resultMap="singleResultMap">
    select * from se_singletrans where transno = #{param1} and commandCode= #{param2}
  </select>
</mapper>

關於TypeHandle這裏不做具體闡述,有興趣的可以看下MyBatis自定義類型處理器 TypeHandler

參考文獻

  1. Maven添加Oracle的依賴及驅動
  2. MyBatis自定義類型處理器 TypeHandler

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

南投搬家公司費用需注意的眉眉角角,別等搬了再說!

新北清潔公司,居家、辦公、裝潢細清專業服務

※教你寫出一流的銷售文案?

【asp.net core 系列】12 數據加密算法

0. 前言

這一篇我們將介紹一下.net core 的加密和解密。在Web應用程序中,用戶的密碼會使用MD5值作為密碼數據存儲起來。而在其他的情況下,也會使用加密和解密的功能。

常見的加密算法分為對稱加密和非對稱加密。所謂的對稱加密是指加密密鑰和解密密鑰是同一個,非對稱加密是值加密密鑰和解密迷藥不同。而我們常應用在保存用戶登錄密碼這個過程中的MD5本質上並不是加密算法,而是一種信息摘要算法。不過MD5盡量保證了每個字符串最後計算出來的值都不一樣,所以在密碼保存中常用MD5做為保密值。

1. 常見對稱加密算法

對稱加密算法,簡單的說就是加密和解密使用相同的密鑰進行運算。對於大多數加密算法,解密和加密是一個互逆的運算。對稱加密算法的安全性取決於密鑰的長度,密鑰越長越安全。當然,不建議使用過長的密鑰。

那麼,我們來看看常見的對稱加密算法有哪些吧,以及C#該如何實現。

1.1 DES 和 DESede 算法

DES算法和DESede算法(又稱三重DES算法) 統稱DES系列算法。DES全稱為Data Encryption Standard,即數據加密標準,是一種使用密鑰加密的塊算法。而DESede就是針對同一塊數據做三次DES加密。這裏就不對原理做過多的介紹了,來看看.net core里如何實現DES加/解密吧。

在Utils項目里,創建目錄Security

在Security目錄下,創建DESHelper類:

namespace Utils.Security
{
    public class DesHelper
    {
        
    }
}

加密解密實現:

using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;

namespace Utils.Security
{
    public static class DesHelper
    {
        static DesHelper()
        {
            DesHandler =  DES.Create("DES");
            DesHandler.Key = Convert.FromBase64String("L1yzjGB2sI4=");
            DesHandler.IV = Convert.FromBase64String("uEcGI4JSAuY=");
        }

        private static DES DesHandler { get; }

        /// <summary>
        /// 加密字符
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static string Encrypt(string source)
        {
            try
            {
                using (var memStream = new MemoryStream())
                using (var cryptStream = new CryptoStream(memStream, DesHandler.CreateEncryptor(DesHandler.Key, DesHandler.IV),
                    CryptoStreamMode.Write))
                {
                    var bytes = Encoding.UTF8.GetBytes(source);
                    cryptStream.Write(bytes, 0, bytes.Length);
                    cryptStream.FlushFinalBlock();
                    
                    return Convert.ToBase64String(memStream.ToArray());
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                return null;
            }
        }

        /// <summary>
        /// 解密
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static string Decrypt(string source)
        {
            try
            {
                using (var mStream = new MemoryStream(Convert.FromBase64String(source)))
                using (var cryptoStream =
                    new CryptoStream(mStream, DesHandler.CreateDecryptor(DesHandler.Key, DesHandler.IV), CryptoStreamMode.Read))
                using (var reader = new StreamReader(cryptoStream))
                {
                    return reader.ReadToEnd();
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                return null;
            }
        }
    }
}

每次調用DesHandler = DES.Create("DES"); 都會重新獲得一個DES算法實現實例,這樣每次獲取的實例中Key、IV這兩個屬性的值也會發生變化。如果直接使用會出現這次加密的數據下次就沒法解密了,為了減少這種情況,所以代碼處手動賦值了Key、IV這兩個屬性。

1.2 AES 加密算法

AES算法(Advanced Encryption Standard)也就是高級數據加密標準算法,是為了解決DES算法中的存在的漏洞而提出的算法標準。現行的AES算法核心是Rijndael算法。當然了,這個不用太過於關心。我們直接看看是如何實現吧:

同樣,在Security目錄創建一個AesHelper類:

namespace Utils.Security
{
    public static class AesHelper
    {
        
    }
}

具體的加解密實現:

using System;
using System.IO;
using System.Security.Cryptography;

namespace Utils.Security
{
    public static class AesHelper
    {
        static AesHelper()
        {
            AesHandler = Aes.Create();
            AesHandler.Key = Convert.FromBase64String("lB2BxrJdI4UUjK3KEZyQ0obuSgavB1SYJuAFq9oVw0Y=");
            AesHandler.IV = Convert.FromBase64String("6lra6ceX26Fazwj1R4PCOg==");
        }

        private static Aes AesHandler { get; }

        public static string Encrypt(string source)
        {
            using (var mem = new MemoryStream())
            using (var stream = new CryptoStream(mem, AesHandler.CreateEncryptor(AesHandler.Key, AesHandler.IV),
                CryptoStreamMode.Write))
            {
                using (var writer = new StreamWriter(stream))
                {
                    writer.Write(source);
                }   
                return Convert.ToBase64String(mem.ToArray());
            }
            
        }

        public static string Decrypt(string source)
        {
            var data = Convert.FromBase64String(source);
            using (var mem = new MemoryStream(data))
            using (var crypto = new CryptoStream(mem, AesHandler.CreateDecryptor(AesHandler.Key, AesHandler.IV),
                CryptoStreamMode.Read))
            using (var reader = new StreamReader(crypto))
            {
                return reader.ReadToEnd();
            }
        }
    }
}

2. 常見非對稱加密算法

非對稱加密算法,指的是加密密鑰和解密密鑰並不相同。非對稱加密算法的秘鑰通常成對出現,分為公開密鑰和私有密鑰。公開密鑰可以以公開的形式發給數據交互方,而不會產生泄密的風險。因為非對稱加密算法,無法通過公開密鑰推算私有密鑰,反之亦然。

通常,非對稱加密算法是用公鑰進行加密,使用私鑰進行解密。

2.1 RSA算法

RSA算法是標準的非對稱加密算法,名字來源是三位發明者的姓氏首字母。RSA公開密鑰密碼體制是一種使用不同的加密密鑰與解密密鑰,“由已知加密密鑰推導出解密密鑰在計算上是不可行的”密碼體制 。其安全性取決於密鑰的長度,1024位的密鑰幾乎不可能被破解。

同樣,在Utils.Security下創建RSAHelper類:

namespace Utils.Security
{
    public static class RsaHelper
    {
        
    }
}

具體實現:

using System;
using System.Security.Cryptography;

namespace Utils.Security
{
    public static class RsaHelper
    {
        public static RSAParameters PublicKey { get; private set; }
        public static RSAParameters PrivateKey { get; private set; }

        static RsaHelper()
        {
            
        }

        public static void InitWindows()
        {
            var parameters = new CspParameters()
            {
                KeyContainerName = "RSAHELPER" // 默認的RSA保存密鑰的容器名稱
            };
            var handle = new RSACryptoServiceProvider(parameters);
            PublicKey = handle.ExportParameters(false);
            PrivateKey = handle.ExportParameters(true);
        }

        public static void ExportKeyPair(string publicKeyXmlString, string privateKeyXmlString)
        {
            var handle  = new RSACryptoServiceProvider();
            handle.FromXmlString(privateKeyXmlString);
            PrivateKey = handle.ExportParameters(true);
            handle.FromXmlString(publicKeyXmlString);
            PublicKey = handle.ExportParameters(false);
        }
        public static byte[] Encrypt(byte[] dataToEncrypt)
        {
            try
            {
                byte[] encryptedData;
                using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider())
                {
                    RSA.ImportParameters(PublicKey);
                    encryptedData = RSA.Encrypt(dataToEncrypt, true);
                }

                return encryptedData;
            }
            catch (CryptographicException e)
            {
                Console.WriteLine(e.Message);
                return null;
            }
        }

        public static byte[] Decrypt(byte[] dataToDecrypt)
        {
            try
            {
                byte[] decryptedData;
                using (var rsa = new RSACryptoServiceProvider())
                {
                    rsa.ImportParameters(PrivateKey);
                    decryptedData = rsa.Decrypt(dataToDecrypt, true);
                }
                return decryptedData;
            }
            catch (CryptographicException e)
            {
                Console.WriteLine(e.ToString());
                return null;
            }
        }
    }
}

因為RSA的特殊性,需要預先設置好公鑰和私鑰。C# 支持多種方式導入密鑰,這裏就不做過多介紹了。

3. 信息摘要算法

這種算法嚴格意義上並不是加密算法,因為它完全不可逆。也就是說,一旦進行使用該類型算法加密后,無法解密還原出數據。當然了,也正是因為這種特性常常被用來做密碼的保存。因為這樣可以避免某些人拿到數據庫與代碼后,可以簡單反推出用戶的密碼。

3.1 MD5算法

最常用的信息摘要算法就是MD5 加密算法,MD5信息摘要算法(英語:MD5 Message-Digest Algorithm),一種被廣泛使用的密碼散列函數,可以產生出一個128位(16字節)的散列值(hash value),用於確保信息傳輸完整一致。

原理不解釋,我們看下如何實現,照例現在Security下創建MD5Helper:

namespace Utils.Security
{
    public static class Md5Helper
    {
        
    }
}

具體實現:

using System.Security.Cryptography;
using System.Text;

namespace Utils.Security
{
    public static class Md5Helper
    {
        private static MD5 Hanlder { get; } = new MD5CryptoServiceProvider();

        public static string GetMd5Str(string source)
        {
            var data = Encoding.UTF8.GetBytes(source);
            var security = Hanlder.ComputeHash(data);
            var sb = new StringBuilder();
            foreach (var b in security)
            {
                sb.Append(b.ToString("X2"));
            }

            return sb.ToString();
        }
    }
}

4 總結

這一篇簡單介紹了四種常用的加密算法的實現,當然最常用的就是 MD5,因為這個是大多數系統用來做密碼保存的加密算法。

更多內容煩請關注我的博客《高先生小屋》

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

※想知道最厲害的網頁設計公司"嚨底家"!

※幫你省時又省力,新北清潔一流服務好口碑

※別再煩惱如何寫文案,掌握八大原則!

※產品缺大量曝光嗎?你需要的是一流包裝設計!

也來聊聊 HTTPS.

前言: 網上聊 HTTPS 的文章已經數都數不過來了吧,厚着臉皮,整理下讀書筆記,結合平常項目的實踐,也來聊聊 HTTPS。

一、為什麼需要 HTTPS?

眾所周知,HTTP 協議具有無連接、不可靠、盡最大努力的特點,這也為 HTPP 協議帶來信息竊聽或身份偽裝等安全問題。主要體現在幾個方面:

  • 通信使用明文(不加密),內容可能會被竊聽。
  • 不驗證通信方的身份,因此有可能遭遇偽裝。
  • 無法證明報文的完整性,所以有可能已遭篡改。

那要如何做到防止竊聽保護信息呢?最為普及的就是加密技術。

  • 通信的加密:用 SSL(Secure Socket Layer,安全套接層)或 TLS(Transport Layer Security,安全層傳輸協議)建立安全通信線路之後,就可以在這條線路上進行 HTTP 通信了。與 SSL/TLS 組合使用的 HTTP 就是 HTTPS,通常 HTTP 直接和 TCP 通信,當使用 SSL 時,則演變成先與 SSL 通信,再由 SSL 和 TCP 通信了,所以 HTTPS 並不是一種新的協議。
  • 內容的加密: 對 HTTP 協議傳輸的內容本身加密,即把 HTTP 報文里所含的內容進行加密處理。

SSL 協議最初是由瀏覽器開發商網景通信公司率先倡導的,開發過 SSL3.0 之前的版本。IETF 以 SSL3.0 為基準,后又制定了 TLS1.0、TLS1.1 和 TLS1.2。TSL 是以 SSL為原型開發的協議,有時會統一稱該協議為 SSL。當前主流的版本是 SSL3.0 和 TLS1.0。

SSL 不僅提供加密處理,而且還使用了一種被稱為證書的手段,可用於確定通信方。

二、HTTPS 怎麼來保障通信安全的?

HTTPS 具有加密、認證以及完整性保護的功能。

1. 加密

客戶端和服務端想要進行安全的通信,首先想到的就是對通信雙方的內容進行加密處理。客戶端利用“密鑰”加密內容,服務端利用“密鑰”解密內容,反之亦然。這種方式稱為對稱(共享密鑰)加密。

對稱加密客戶端和服務端的“密鑰”是一致的,因此,客戶端和服務端之間的“密鑰”傳輸不可避免,如果“密鑰”在傳輸途中被盜用,那麼加密處理就沒有意義了。

那麼如何保護“密鑰”的傳輸安全呢?實踐的思路是非對稱(公開密鑰)加密,服務端擁有 公鑰(public key)+ 私鑰(private key)的密鑰對,公鑰任何人都可以獲取,私鑰只保存在服務端。以下是 SSL 建立安全通信線路的過程。

  1. 服務端將公鑰傳輸給客戶端。
  2. 客戶端通過公鑰加密“密鑰”(客戶端生成)得到一個加密串並傳輸給服務端。
  3. 服務端根據私鑰解密加密串得到“密鑰”。
  4. 雙方通過“密鑰”加密傳輸。

非對稱加密“密鑰”的方式很好的保障了“密鑰”的安全傳輸,因為即使傳輸過程中加密串被盜用了,由於盜用者沒有私鑰信息,也無法得到加密串中的“密鑰”信息。

HTTPS 採用對稱(共享密鑰)加密和非對稱(公開密鑰)加密兩者並用的混合加密機制。之所以要這麼複雜,是因為非對稱加密的處理速度相較於對稱加密要慢,因此,我們一般在交換“密鑰”環節使用非對稱加密,之後的建立通信交換報文階段則使用對稱加密方式。

2. 認證

遺憾的是,非對稱加密傳輸“密鑰”的方式仍然有缺陷,那就是無法證明服務器公鑰本身就是貨真價實的公鑰。比如,接收到某台服務器的公鑰,如何證明公鑰就是原本預想的那台服務器發行的公鑰呢?或許在公鑰傳輸途中,真正的公鑰已經被攻擊者替換掉了。

計算機科學領域的任何問題都可以通過增加一個間接的中間層來解決。

這裏我們引入的中間層就是数字證書認證機構(CA,Certificate Authority),数字證書認證機構處於客戶端與服務器雙方都可信賴的第三方機構的立場上,以下是数字證書認證機構的業務流程。

  1. 服務器的運營人員向数字證書認證機構提出公開密鑰的申請。
  2. 数字證書認證機構在判明提出申請者的身份之後,會對已申請的公開密鑰做数字簽名,然後分配這個已簽名的公開密鑰,並將該公開密鑰放入公鑰證書。
  3. 服務器將公鑰證書下發給客戶端。
  4. 客戶端使用公鑰證書的公開密鑰,對那張證書上的数字簽名進行驗證,一旦驗證通過,客戶端便可明確兩件事:一,認證服務器的公開密鑰的是真實有效的数字證書認證機構頒發的。二,服務器的公開密鑰是值得信賴的。

HTTPS 中還可以使用客戶端證書,以客戶端證書進行客戶端認證,證明服務器正在通信的對方始終是預料之內的客戶端,其作用跟服務器證書如出一轍。

使用 OpenSSL 這套開源程序,每個人都可以構建一套屬於自己的認證機構,從而自己給自己頒發服務器證書,但該服務器證書在互聯網上不可作為證書使用,因為個人並不是可信任的三方機構。

3. 完整性保護

基於 SSL 進行 HTTP 通信時,應用層發送數據會附加一種叫做 MAC(Message Authentication Code)的報文摘要,MAC 能夠查知報文是否遭到篡改,從而保護報文的完整性。

三、HTTPS 的通信過程

CBC 模式(Cipher Block Chaining)又名密碼分組鏈接模式。在此模式下,將前一個明文塊加密處理后和下一個明文塊做 XOR 運算,使之重疊,然後再對運算結果做加密處理。 對第一個明文塊做加密時,要麼使用前一段密文的最後一塊,要麼利用外部生成的初始向量(initial vector, IV)。

四、HTTPS 的缺點?

處理速度上,由於 HTTPS 還需要做服務器、客戶端雙方加密及解密過程,因此會消耗 CPU 和內存等硬件資源。

通信上,和單純 HTTP 通信相比,SSL 通信會消耗部分網絡資源。

綜上所述,相較於 HTTP 通信來說,HTTPS 通信速度會變慢。針對速度變慢這一問題,並沒有根本性的解決方案,我們會使用 SSL 加速器這種(專用服務器)硬件來改善該問題。 該硬件為 SS通信專用硬件,相對軟件來講,能夠提高數倍 SSL 的計算速度。

另外,SSL 證書的費用開銷也是使用 HTTPS 的考慮因素之一(阿里雲/騰訊雲有免費的 SSL 證書可以申請使用)。

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

新北清潔公司,居家、辦公、裝潢細清專業服務

※別再煩惱如何寫文案,掌握八大原則!

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

※超省錢租車方案

※教你寫出一流的銷售文案?

網頁設計最專業,超強功能平台可客製化

蓄意污染亞馬遜雨林 雪佛龍在厄瓜多憲法法庭敗訴

環境資訊中心外電;姜唯 翻譯;林大利 審校;稿源:ENS

美國雪佛龍(Chevron)公司的世紀污染訴訟案,有了最新進展。厄瓜多憲法法庭稍早駁回了雪佛龍對95億美元污染判決的最終上訴,認定該公司蓄意將數十億加侖的有毒油廢料傾倒在亞馬遜熱帶雨林的原民土地上。

長達151頁的判決書中,以8比0一致判定原告原民團體勝訴,並駁回了雪佛龍的所有說法,例如雪佛龍自己也是詐欺受害者,以及厄瓜多法院對此案無管轄權等都遭到駁回。

前油田運營商德士古(後被雪佛龍收購)蓄意將數十億加侖的有毒油廢料傾倒在亞馬遜熱帶雨林。圖片來源:Caroline Bennett / Rainforest Action Network

環境集體訴訟案 第四次獲勝

厄瓜多憲法法院僅審理憲法問題,是厄瓜多第三大上訴法院,也是該國第四個維持2011年判決結果的法院,連同厄瓜多最高民事法庭和國家法院一致裁定雪佛龍須做出鉅額賠償。

這個針對雪佛龍公司的集體訴訟案,判決書於7月11日發布,原告是守護亞馬遜陣線(Frente de Defensa de la Amazonia),代表厄瓜多亞馬遜北部地區80個原民和農民社區的草根團體。

該訴訟最初由約3萬名熱帶雨林村民於1993年在紐約聯邦法院提出,被告是前油田運營商德士古(Texaco,已被雪佛龍公司收購)。2001年雪佛龍公司接受厄瓜多具有管轄權後,一名美國聯邦法官將此案移交給厄瓜多法院。

「這個判決是厄瓜多人民20年來為了爭取環境正義,對抗世界級污染者、流氓企業的再一次巨大勝利,」環保金人獎得主、1993年訴訟案起草者楊澤(Luis Yanza)表示。他目前也是守護亞馬遜陣線的主席。

楊澤說:「在雪佛龍開始賠償厄瓜多人民前,任何國家都不應該與雪佛龍做生意。」

致癌油廢料污染 雪佛龍八年拖延纏訟

厄瓜多首席律師薩拉查(Patricio Salazar)表示,「司法已認定雪佛龍非法攻擊代表原住民社群的律師,而不是根據是非來訴訟。雪佛龍現在極有可能必須全額支付賠償金,因為它在法律上和道德上都有義務這樣做。」

厄瓜多初審法院依據105份技術證據報告,在2011年判決該公司致癌油廢料污染了1500平方英里的亞馬遜土地。但是八年來,雪佛龍以拖延戰術因應訴訟。

生活在熱帶雨林中的數千人,包括許多原住民,已經死於癌症,而成千上萬的人必須忍受這場世界級的公衛災難。

代表厄瓜多村民的美國律師唐齊格(Steven Donziger)。圖片來源:Steven Donziger

拒支付賠償金 村民仍沒有醫療

收受雪佛龍公司400口油井特許使用費的厄瓜多政府,沒有給受害者太大幫助。

哈佛大學畢業,代表厄瓜多村民的美國律師唐齊格(Steven Donziger)曾走訪受影響地區數十次,他表示受影響地區並沒有醫療服務,許多人甚至一次醫生都沒看,也沒接受任何治療就死於癌症。

「雪佛龍在厄瓜多引發了一場史無前例的人道主義危機。再不清除污染,未來幾年將有數萬人死亡。全世界都必須關注,雪佛龍的股東和管理層必須立即採取行動,解決這個日益嚴重的問題。」唐齊格說。

雪佛龍多年來一直拒絕支付判決賠償金,目前連本帶利已經來到120億美元(約新台幣1361億元)。

雪佛龍公司人員甚至威脅原民,若繼續堅持訴訟,他們可和原告「終身纏訟」。

卡普蘭法官 採信偽證風波

這份最新判決也是對美國紐約南區地方法院法官卡普蘭(Lewis A. Kaplan)的重大打擊。

2014年,這位具有爭議性的法官僅憑一位承認收賄的雪佛龍證人的假證詞便裁定,厄瓜多最高法院對雪佛龍提出的95億美元賠償判決是透過欺詐和脅迫手段取得。卡普蘭拒絕讓公正的事實調查員陪審團參與,也拒絕考量任何有關雪佛龍污染厄瓜多環境的證據。

但新事證顯示,雪佛龍支付厄瓜多前法官格拉(Alberto Guerra)大筆賄款之後,卡普蘭的判決被推翻。雪佛龍幫助格拉一家搬到美國後,格拉承認在雪佛龍律師的指導下作偽證。

卡普蘭僅憑格拉的偽證做出判決,也是全世界唯一做出有利雪佛龍判決的法官。

「出於省錢的錯誤營運決策」 法庭定調蓄意污染

基於比卡普蘭所能取得更完整的證據,17名厄瓜多法官作出有利厄瓜多村民的判決。12名加拿大法官,包括該國最高法院,也針對多個技術性問題作出有利厄瓜多村民的判決。

厄瓜多憲法法庭強調,雪佛龍污染環境造成嚴重後果不是意外造成,而是處心積慮為公司和股東省錢的運營決策,加上20年來蓄意拖延的額外罪行所導致。

厄瓜多原告也在加拿大法院取得了幾項上訴勝利,他們在加國蒐集雪佛龍資產,以迫使其遵守厄瓜多的判決。

Chevron Defeated in Ecuador’s Constitutional Court QUITO, Ecuador, July 31, 2018 (ENS)

In a benchmark pollution case, Ecuador’s Constitutional Court has rejected Chevron’s final appeal of a $9.5 billion pollution judgment that found the company deliberately dumped billions of gallons of toxic oil waste onto Indigenous lands in the Amazon rainforest.

Photo: Caroline Bennett / Rainforest Action Network

The unanimous 8-0 decision, issued in a 151-page document published July 11, was a total victory for the Indigenous groups that brought the case and a rejection of all of Chevron’s claims.

The Court rejected Chevron’s allegations that it was victimized by fraud, and the court threw out the company’s claim that Ecuadorian courts had no jurisdiction over the matter.

Ecuador’s Constitutional Court, which deals only with Constitutional issues, is the third major appellate court in Ecuador and the fourth court overall in the country to uphold the trial-level decision against Chevron, which was issued in 2011. Ecuador’s highest civil court, the National Court of Justice, has ruled unanimously to affirm the judgment against Chevron.

The class action case against Chevron was spearheaded by the Frente de Defensa de la Amazonia, the Amazon Defense Front, a grassroots group representing 80 Indigenous peoples and farmer communities in Ecuador’s northern Amazon region.

The case was originally filed in 1993 in federal court in New York against the former oil field operator Texaco, now part of Chevron Corporation, on behalf of an estimated 30,000 rainforest villagers. But in 2001 a U.S. federal judge moved it to Ecuador’s courts at Chevron’s request after the company accepted jurisdiction there.

“This decision is another huge victory for the people of Ecuador in their historic two-decade battle for environmental justice against the world’s worst corporate polluter and rogue operator,” said Luis Yanza, a Goldman Prize winner who initiated the lawsuit against Chevron in U.S. federal court in 1993, and serves as president of the Frente de Defensa de la Amazonia, Amazon Defense Front.

“No country should ever do business with Chevron until the company first pays for the harm it caused to the people of Ecuador,” Yanza said.

Patricio Salazar, the lead Ecuadorian lawyer on the case, said, “Justice has prevailed over Chevron’s illegal attempts to engage in constant attacks on lawyers who defend the Indigenous communities rather than litigate in good faith on the merits. It is now highly likely that Chevron will pay every last dollar of the judgment against it, as it is legally and ethically obligated to do.”

After eight years of proceedings slowed by Chevron’s strategy of deliberate delay, Ecuador’s trial court relied on 105 technical evidentiary reports to find in 2011 that the company poisoned a 1,500 square mile area of the Amazon with carcinogenic oil waste.

Thousands who live in the rainforest, including many Indigenous peoples, have died of cancer while tens of thousands must endure what is one of the world’s worst ongoing public health catastrophes.

Photo: Jonathan McIntosh / Rainforest Action Network

Ecuador’s government, which received royalties from Chevron’s operation of 400 well sites, has been of little help to the victims. Medical care in the affected region is non-existent, and many people perish from cancer without even visiting a doctor and after receiving no treatment, said Steven Donziger, the Harvard educated U.S. legal representative of the Ecuadorian communities, who has taken dozens of trips to the affected area.

“Chevron has caused a humanitarian crisis in Ecuador of epic proportions that is ongoing to this day,” he said. “Tens of thousands of people will die in the coming years if nothing is done to clean up the pollution. The world must pay attention and Chevron shareholders and management must act immediately to address this worsening problem.”

Chevron has refused for years to pay the Ecuador judgment, now worth $12 billion with interest. Company officials have threatened the Indigenous groups with a “lifetime of litigation” if they persist.

The latest Ecuadorean court decision is also a major blow to controversial Judge Lewis A. Kaplan, a judge of the U.S. District Court for the Southern District of New York.

In 2014, Judge Kaplan ruled that the $9.5 billion Lago Agrio judgment leveled against Chevron by Ecuador’s highest court, was obtained by way of fraud and coercion.

Kaplan relied on false testimony from an admittedly corrupt Chevron witness to find that the Ecuador judgment was procured by fraud. Kaplan refused to seat a jury of impartial fact finders, and he refused to consider any evidence of Chevron’s environmental contamination in Ecuador.

But Kaplan’s decision was disproven after evidence emerged that Chevron paid large sums to Alberto Guerra, a former Ecuadorian judge booted from the bench after he admitted taking bribes. Guerra was moved with his family by Chevron to the United States and later admitted lying on the stand after being coached for 53 days by Chevron lawyers headed by Randy Mastro at Gibson Dunn.

Kaplan based his core findings largely on Guerra’s false testimony. And Kaplan remains the only judge in the world to have ruled in favor of Chevron.

Seventeen Ecuador judges, who had access to a fuller evidentiary record than Kaplan, ruled in favor of the affected communities. Twelve judges from Canada, including the country’s entire Supreme Court, have also ruled in favor of the Ecuadorians on various technical issues.

The Ecuador decision confronts Chevron on the brutal human consequences of both its original environmental crimes, which the Court emphasizes were not the result of an accident, but rather of deliberate operational decision-making designed to save money and enrich the company’s shareholders and executives, and the additional offense of its two-decade campaign of distraction and delay.

The Ecuadorian plaintiffs also have picked up several appellate victories in Canadian courts as they attempt to collect Chevron assets in that country to force compliance with the Ecuador judgment.

※ 全文及圖片詳見:

作者

如果有一件事是重要的,如果能為孩子實現一個願望,那就是人類與大自然和諧共存。

於特有生物研究保育中心服務,小鳥和棲地是主要的研究對象。是龜毛的讀者,認為龜毛是探索世界的美德。

延伸閱讀

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※為什麼 USB CONNECTOR 是電子產業重要的元件?

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

※台北網頁設計公司全省服務真心推薦

※想知道最厲害的網頁設計公司"嚨底家"!

新北清潔公司,居家、辦公、裝潢細清專業服務

※推薦評價好的iphone維修中心

不能放任蜜蜂死 法國禁五款類尼古丁農藥

摘錄自2018年8月10日中央社報導

法國政府為遏止蜜蜂持續大量死亡,公告自9月1日起禁用五種含類尼古丁的農藥。

法國於2016年實施生物多樣性法規,當時就決定要禁用含類尼古丁(neonicotinoid)的殺蟲劑,這種物質會破壞昆蟲的神經系統,導致蜜蜂等花粉媒介昆蟲迷路及死亡,威脅到生物多樣性和糧食生產。

法國這一波禁用的五種殺蟲劑包括益達胺(imidacloprid)、可尼丁(clothianidin)、賽速安(Thiamethoxam)、賽果培(Thiacloprid)和亞滅培(Acetamiprid)。

法國政府對這類殺蟲劑的禁令比歐盟嚴格。費加洛報(Le Figaro)報導,法國生態部表示,國會正在審議糧食法草案,通過後,應可再增加禁用類尼古丁殺蟲劑的種類。

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

※想知道購買電動車哪裡補助最多?台中電動車補助資訊懶人包彙整

南投搬家公司費用,距離,噸數怎麼算?達人教你簡易估價知識!

※教你寫出一流的銷售文案?

※超省錢租車方案