海關“龍騰行動2019”扣留侵權嫌疑貨物超1700萬件_台中搬家

台中搬家公司費用怎麼算?

擁有20年純熟搬遷經驗,提供免費估價且流程透明更是5星評價的搬家公司

新華社北京1月25日電(記者劉紅霞)記者近日從海關總署獲悉,以打擊侵權假冒為主題的海關“龍騰行動2019”專項行動戰果豐碩,共扣留侵權嫌疑貨物4.5萬批,涉及貨物1745萬件,價值1.07億元。

據了解,本次專項行動為期6個月,持續至2019年年底。專項行動期間,全國海關查獲涉及我國自主品牌侵權嫌疑貨物356批,扣留侵權貨物627.1萬件,價值3019.78萬元;對外資品牌實施保護措施8617次,查獲侵犯外資品牌貨物4.23萬批,涉及貨物1032.57萬件,價值6239.38萬元。

以廣州海關為例,專項行動期間,廣州海關共查扣侵權嫌疑貨物1941批次、264.1萬件,129家知識產權權利人的406項知識產權得到保護。

台中搬家遵守搬運三大原則,讓您的家具不再被破壞!

台中搬家公司推薦超過30年經驗,首選台中大展搬家

廣州海關綜合業務處處長唐慶林說,專項行動主要聚焦消費电子類產品、汽車配件、個人護理用品、服裝、箱包、鞋靴等涉及公眾健康安全的商品,加大了對重點國家和地區的貨物監管力度。

據介紹,全國海關充分依託“金關二期郵遞物品信息化管理系統”“智能審圖系統”“快件輔助申報平台”等科技手段,開展多角度立體分析和“精準畫像”,並加強區域協作,有效控制侵權商品口岸漂移態勢。

“專項行動期間,全國海關共開展各層級關際合作200餘次,區域聯動、跨區作戰體系初步形成,侵權商品口岸漂移態勢得到有效控制。”海關方面有關負責人說。

區域協作加強的同時,我國海關在打擊侵權假冒方面也在不斷加強國際合作,與歐盟、日本、俄羅斯等國家和地區海關的案件信息通報更加密切。

本站聲明:網站內容來http://www.societynews.cn/html/wh/fq/,如有侵權,請聯繫我們,我們將及時處理

台中搬家遵守搬運三大原則,讓您的家具不再被破壞!

台中搬家公司推薦超過30年經驗,首選台中大展搬家

外媒票選 2020 年最討人厭手機設計,湊數用鏡頭勇奪第一_台中搬家

台中搬家遵守搬運三大原則,讓您的家具不再被破壞!

台中搬家公司推薦超過30年經驗,首選台中大展搬家

2021 年的開始也是 2020 年的結束,過去一年的智慧型手機上出現眾多讓人驚豔的設計,也有許多讓消費者覺得無言的設計,從中當然也看到許多新趨勢的崛起,其中當然也有大家其實並不想看見的設計。國外媒體發起了一項開放式票選,最不受消費者青睞的前三名在 2021 年應該會有越來越多手機具備。

外媒票選 2020 年最討人厭手機設計,湊數用鏡頭勇奪第一

在 GSMArena 票選結果公布後,無用的相機模組成為現在智慧型手機中最受讀者討厭的設計。各家廠商比拚鏡頭數量的潮流其實並不是在 2020 年才開始有,但是像 ToF、語焉不詳的 AI 感測器,甚至微距鏡頭等,其實對一般消費者來說很少會用到,而且也不會讓手機看起來更好或有加分作用,這似乎與當初原廠手機設計的初衷有所出入。

最討人厭的第二名則是省略了幾乎所有隨機附贈的配件。Apple 一直是各家手機業者的風向球,在今年推出 iPhone 12 系列時,Apple 將包裝盒內的配件最少化,這點也勢必會引起各家業者的效仿,目前第一個跟隨者就是甫發表的小米 11,雖說它還提供了包含充電設備的加量不加價套裝,但在 2021 年應該會有更多廠商跟進。

而從網友發表的評論意見中,瀏海與打洞螢幕依然不是太討喜的設計,只是螢幕下前鏡頭的普及還有很長一段時間。且還有許多人對小型手機趕到不滿意,除了小型經濟實惠的機型,小型旗艦也不受寵。相比於小尺寸手機來說,更惱人的就是因為手機體型變小而跟著縮小的電池,在手機廠商陷入了快充速度競爭中,雖說 100W 充電能夠成為媒體競相報導的頭條,但對大多數用戶來說,更希望有不需要經常充電的手機。

台中搬家公司費用怎麼算?

擁有20年純熟搬遷經驗,提供免費估價且流程透明更是5星評價的搬家公司

上面這些不被喜歡的設計卻很有可能是 2021 年變成常態,下面與大家分享一下整體的投票結果,對你來說最不喜歡的設計會是什麼呢?

◎資料來源:GSMArena

您也許會喜歡:

【推爆】終身$0月租 打電話只要1元/分

立達合法徵信社-讓您安心的選擇

台中搬家公司費用怎麼算?

擁有20年純熟搬遷經驗,提供免費估價且流程透明更是5星評價的搬家公司

沒有ABS沒有安全氣囊?你敢買這些國產車那是不要命!_台中搬家

台中搬家公司費用怎麼算?

擁有20年純熟搬遷經驗,提供免費估價且流程透明更是5星評價的搬家公司

不過在安全配置確實寒磣的,最低配沒有安全氣囊、ABS防抱死系統,低配則只有一個安全氣囊,為了安全着想,建議大家選擇4。68萬起的手動時尚版或者更高版本。3吉利-自由艦吉利自由艦以及是一輛家喻戶曉的車型了,甚至不少人的上一輛汽車是自由艦。

前言

ABS防抱死系統,相信大家都知道這是一個非常重要的裝置,它可以在我們緊急剎車時還保留着一定的轉向能力以躲避危險。所以國家已經有着法規將其作為強制安裝的裝置,不過在某些車型上,依然為了成本以及售價不提供ABS防抱死系統,倘若在不知情的情況購買了這些車型,生命安全就處於沒有保障的地步。

說到哪一款5萬以下的汽車最受年輕人歡迎的話,比亞迪F0肯定榜上有名,它憑着低廉的價格、比較時尚的外形以及不俗的改裝潛力、低保養維修成本,使得不少在校大學生或者剛剛走進社會的年輕人選擇這款小車。但是在安全配置上因為成本的原因,低得令人髮指,中低配下都是沒有安全氣囊以及ABS防抱死系統,加上165/60 R14的低規格輪胎,

台中搬家遵守搬運三大原則,讓您的家具不再被破壞!

台中搬家公司推薦超過30年經驗,首選台中大展搬家

使得它駕駛時的穩定性以及安全性受到深大的質疑。

寶駿310是最近上市的新車,在上市之初就憑着“用一部iphone的價格給首付”去吸引年輕人,3.68-4.98萬的官方指導價加上免息,使得很多年輕人都願意去買這款同價位中顏值最高、同級別中最為優秀的小型車,而且它使用了电子轉向助力系統,在手感上要明顯好於競爭對手。不過在安全配置確實寒磣的,最低配沒有安全氣囊、ABS防抱死系統,低配則只有一個安全氣囊,為了安全着想,建議大家選擇4.68萬起的手動時尚版或者更高版本。

吉利自由艦以及是一輛家喻戶曉的車型了,甚至不少人的上一輛汽車是自由艦。它是吉利沉積豐田夏利平台的產物,在整車質量是相當的可靠,1.3L發動機雖然動力一般,但卻有着維修保養費用低廉的優點。不過在安全配置上就有點說不過去了,低配上竟然沒有配備安全氣囊,甚至連ABS防抱死系統,雖說價格僅僅是3.89萬但我們依然是不建議購買,建議選擇僅僅高3000元的高配,與此相比多了安全氣囊以及ABS防抱死系統。本站聲明:網站內容來源於http://www.auto6s.com/,如有侵權,請聯繫我們,我們將及時處理

台中搬家公司費用怎麼算?

擁有20年純熟搬遷經驗,提供免費估價且流程透明更是5星評價的搬家公司

itext7史上最全實戰總結_台中搬家

台中搬家公司費用怎麼算?

擁有20年純熟搬遷經驗,提供免費估價且流程透明更是5星評價的搬家公司

1. itext7史上最全實戰總結

1.1. 前言

最近有個需求需要我用Java手動寫一份PDF報告,經過考察幾種pdf開源代碼,最終選取了itext7,此版本為7.1.11,由於發現網上關於該工具的博文比較少,特別是實戰博文幾乎沒有,在我踩完各種坑,最終把PDF成型后,打算把經驗分享出來,本文通過摘錄解釋來說明,內容來自本人GitHub itext-pdf

1.2. 配置文件

項目採用了Spring Cloud config所以配置在git上,僅僅研究itext7不需要用到數據庫等功能,請直接運行PdfMain類的main方法,即可生成模擬的PDF報告

1.3. 版本POM

itext7相關pom

<properties>
    <itext.version>7.1.11</itext.version>
</properties>
<dependencies>
    <!-- itext7 -->
    <dependency>
        <groupId>com.itextpdf</groupId>
        <artifactId>kernel</artifactId>
        <version>${itext.version}</version>
    </dependency>
    <dependency>
        <groupId>com.itextpdf</groupId>
        <artifactId>io</artifactId>
        <version>${itext.version}</version>
    </dependency>
    <dependency>
        <groupId>com.itextpdf</groupId>
        <artifactId>layout</artifactId>
        <version>${itext.version}</version>
    </dependency>
    <dependency>
        <groupId>com.itextpdf</groupId>
        <artifactId>forms</artifactId>
        <version>${itext.version}</version>
    </dependency>
    <dependency>
        <groupId>com.itextpdf</groupId>
        <artifactId>pdfa</artifactId>
        <version>${itext.version}</version>
    </dependency>
    <dependency>
        <groupId>com.itextpdf</groupId>
        <artifactId>pdftest</artifactId>
        <version>${itext.version}</version>
    </dependency>
    <dependency>
        <groupId>com.itextpdf</groupId>
        <artifactId>font-asian</artifactId>
        <version>${itext.version}</version>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-log4j12</artifactId>
        <version>1.7.18</version>
    </dependency>

    <!--itext7 html轉pdf用到的包-->
    <dependency>
        <groupId>com.itextpdf</groupId>
        <artifactId>html2pdf</artifactId>
        <version>3.0.0</version>
    </dependency>
</dependencies>

1.4. 乾貨

itext7語義本身和前端css很像,所以有點前端基礎還是比較容易掌握的

1.4.1. 添加圖片

  1. 讀取項目中圖片文件
  2. 設置邊距
  3. 設置寬高擴大縮小
Image indexImage = new Image(ImageDataFactory.create(GenoReportBuilder.class.getClassLoader().getResource("image/gene.png")));
indexImage.setMargins(-50, -60, -60, -60);
indexImage.scale(1, 1.05f);

1.4.2. 添加指定空白頁

  1. 添加第2頁為空白頁,立即刷新后再繼續添加
pdf.addNewPage(2).flush();

1.4.3. Div、Paragraph

    Div div = new Div();
    div.setWidth(UnitValue.createPercentValue(100));
    div.setHeight(UnitValue.createPercentValue(100));
    div.setHorizontalAlignment(HorizontalAlignment.CENTER);
    Paragraph p1 = new Paragraph();
    p1.setHorizontalAlignment(HorizontalAlignment.CENTER);
    p1.setMaxWidth(UnitValue.createPercentValue(75));
    p1.setMarginTop(180f);
    p1.setCharacterSpacing(0.4f);
    Style large = new Style();
    large.setFontSize(22);
    large.setFontColor(GenoColor.getThemeColor());
    p1.add(new Text("尊敬的 ").addStyle(large));
    ...
    Paragraph p2 = new Paragraph();
    ...
    div.add(p1);
    div.add(p2);
  1. 整塊的內容用Div包裹,這裏整塊包裹的好處是什麼?一方面排版分明成體系,另一方面若需求是整塊的內容必須在同一個版面,你可以對Div設置div.setKeepTogether(true);,盡量保證若整塊的內容超出了一頁,那這塊內容會自動整塊出現在下一頁,上一頁剩下的就留白了
  2. 可以看到DivParagraph可以設置很多屬性,實際上我們常用的組件除了這兩種,還有TableCellList,他們大部分的屬性都是一樣的,只是部分屬性只在部分組件起效果,所以當你設置某個屬性沒起效果也不用奇怪
  3. Paragraph需要特別注意的一點,想要段落文字居中,不要用setHorizontalAlignment(HorizontalAlignment.CENTER);這是組件的居中對段落無效,甚至對段落里你放Text也無效,需要改用setTextAlignment(TextAlignment.CENTER);
  4. Paragraph段落的行距也是個高頻問題,這裏給出官方我看到的解釋,參考https://itextpdf.com/en/resources/books/itext-7-building-blocks/chapter-4-adding-abstractelement-objects-part-1,搜關鍵字setFixedLeading,我的理解該方法設值行高絕對值,官方解釋是兩行文字中間基線之間的距離
  5. 如果想了解詳細的什麼屬性哪裡能起作用哪裡不行,請訪問該地址

1.4.4. Table

  1. useAllAvailableWidth表示頁面有多寬,我就有多寬
  2. table.startNewRow();表示新起一行,table每畫一行都要新起一行
  3. 同樣table內容需要居中,和段落一樣,請設置new Cell().setTextAlignment(TextAlignment.CENTER)
  4. 每個table中cell都有默認高度,會比實際輸入字體高些,此時設置setHeight,若更大沒有問題,若高度小於或接近字體大小文字可能就消失了,若想讓Cell高度更接近文字高度,請設置Cellpadding,即cell.setPadding(-2),設置負值即可

1.4.5. Tab,\t

  1. itext7中如果要表示段落前的空格,不能使用\t,但換行可以使用\n

  2. 若要實現Tab效果可以有多個方法

    1. \u00a0符號,大概7、8個該符號可表示tab,可能不是很準確
    p1.add(new Text("\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0壹基因衷心祝願您身體健康、享受品質生活!"));
    
    1. p1.setFirstLineIndent(24),表示段落前留多少空,需要知道一個字多大,設置成兩倍就行
    2. Tab也是集成AbstractElement的組件,通過以下方式也可實現相同的效果
      p2.add(new Tab());
      p2.addTabStops(new TabStop(20, TabAlignment.LEFT));
    

1.4.6. 換頁

我常用的換頁方法為如下,該方法可保證立即換頁

doc.add(new AreaBreak(AreaBreakType.NEXT_PAGE));

當然PdfDocumentaddNewPage其實也可以用,但有時候你沒把握好刷新時間可能導致某些混亂

1.4.7. 畫圖或畫文字

能畫出多麼複雜的圖形看是誰畫了,在我的PDF中,我畫的最複雜的圖形如下

該圖形由多個弧形區域加線段加文字組成,包括数字上的小箭頭也是畫出來的,畫這個的代碼過多,想要了解詳細的可以自行下載研究,這裏介紹API功能

  1. lineTo畫線段
  2. roundRectangle可用來畫角是弧形的方形,也可以用來畫圓
  3. showText用來畫文字

以上幾種結合填充即可把三角形,多邊形畫出來了

    PdfPage page = pdf.getPage(pdf.getNumberOfPages());
    pageSize = pdf.getDefaultPageSize();
    PdfCanvas pdfCanvas = new PdfCanvas(page);

    pdfCanvas.saveState().moveTo(pageSize.getWidth() / 2 - 100 + i * 40, yOffset - 203)
                    .lineTo(pageSize.getWidth() / 2 - 100 + i * 40, yOffset - 208)
                    .stroke().restoreState();

    pdfCanvas.setLineWidth(2);
        pdfCanvas.setStrokeColor(color);
        pdfCanvas.roundRectangle(pageSize.getWidth() / 2 - 3 + posXOffset, yOffset - 188, 6, 6, 3)
                .stroke();

    pdfCanvas.beginText()
                .setFontAndSize(font, 12)
                .moveText(pageSize.getWidth() / 2 - text.length() * 12 / 2, yOffset - 45);
        pdfCanvas.showText(text);
        pdfCanvas.endText();

1.4.8. Html段落轉Pdf段落

我們可能遇到把一段Html文本轉換成itext7的段落放進來,此時需要用到它的htmlToPdf模塊,該模塊對應POM

    <!--itext7 html轉pdf用到的包-->
    <dependency>
        <groupId>com.itextpdf</groupId>
        <artifactId>html2pdf</artifactId>
        <version>3.0.0</version>
    </dependency>

至於使用,設置好配置屬性,使用也很簡單,通常我們需要支持中文,所有配置如下,字體可以自己換

台中搬家遵守搬運三大原則,讓您的家具不再被破壞!

台中搬家公司推薦超過30年經驗,首選台中大展搬家

    ConverterProperties proper = new ConverterProperties();
    //字體設置,解決中文不显示問題
    FontSet fontSet = new FontSet();
    fontSet.addFont(GenoReportBuilder.class.getClassLoader().getResource("font/SourceHanSansCN-Regular.ttf").getPath(), PdfEncodings.IDENTITY_H);

    FontProvider fontProvider = new FontProvider(fontSet);
    proper.setFontProvider(fontProvider);

    String content = "html內容";
    List<IElement> elements = HtmlConverter.convertToElements(content, proper);

轉換的內容是IElement集合,而IElement是什麼呢?給張圖就了解了

也就是說只要你的html內容是<div></div>包裹的,你直接把元素轉成itext7的Div然後adddocument就可以實現html內容的添加了,當然你也可以用instanceof判斷不同內容不同處理

如下是我的處理例子供參考,我把輸入html內容樣式進行了一定修改後轉成itext7組件,這裏特別提心,html轉過來的itext7組件可能會不支持部分樣式的修改,所以需要在html中進行css樣式的添加,這裏我就把字體和高度統一用css設值了

    Div overall = new Div();
    java.util.List<IElement> iElements = getFixContent(value);
    for (IElement iElement : iElements) {
        Style style = new Style();
        style.setFontSize(10);
        style.setCharacterSpacing(0.7f);
        if (iElement instanceof Div) {
            Div div = (Div) iElement;
            java.util.List<IElement> children = div.getChildren();
            // 全部段落改成相同樣式
            this.addParagraphStyleCircle(style, children);
            overall.add(div);
        } else if (iElement instanceof Paragraph) {
            Paragraph element = (Paragraph) iElement;
            overall.add(element.addStyle(style));
        }
    }
    doc.add(overall);
  • getFixContent
    private java.util.List<IElement> getFixContent(String content) {
        if (content.startsWith("<div>")) {
            content = content.replaceAll("<div>", "<div style='line-height:18pt;font-size:16px;'>");
        } else {
            content = "<div style='line-height:18pt;font-size:16px;'>" + content + "</div>";
        }
        return HtmlConverter.convertToElements(content, proper);
    }
  • addParagraphStyleCircle
    private void addParagraphStyleCircle(Style style, java.util.List<IElement> children) {
        for (IElement child : children) {
            if (child instanceof Paragraph) {
                Paragraph element = (Paragraph) child;
                element.addStyle(style);
                java.util.List<IElement> children1 = element.getChildren();
                this.addParagraphStyleCircle(style, children1);
            }
            if (child instanceof Div) {
                Div div = (Div) child;
                java.util.List<IElement> children1 = div.getChildren();
                this.addParagraphStyleCircle(style, children1);
            }
            if (child instanceof Text) {
                Text text = (Text) child;
                text.addStyle(style);
            }
        }
    }

1.4.9. 監聽事件

在編寫pdf的時候,比如一篇整體的文章,我們需要在頁眉位置添加關於這篇文章的固定文本或者圖形,類似於打個標籤,表示你翻了這麼多頁一直在看這篇文章,當第二篇文章的時候就換一個,舉個例子

  • 第一頁
  • 第二頁

這種需求我們如何實現呢?思路分析發現,我們需要知道什麼時候文章內容一頁寫不起了,換了一頁的時候我們需要添加一個同樣的頁眉。這樣我們就需要知道頁是何時添加的,監聽事件就是處理這種問題的

  • pdf是PdfDocument,可添加的事件有START_PAGEINSERT_PAGEREMOVE_PAGEEND_PAGE共四個,如上需求我們需要監聽START_PAGE事件,在事件處理中做相應的處理,我在事件中使用PdfCanvas畫了頭部內容
HeaderTextEvent headerTextEvent = new HeaderTextEvent(title, font);
pdf.addEventHandler(PdfDocumentEvent.START_PAGE, headerTextEvent);
  • HeaderTextEvent類,Painting僅僅是封裝了PdfCanvas
public class HeaderTextEvent implements IEventHandler {

    private String text;
    private PdfFont font;

    public HeaderTextEvent(String text,PdfFont font) {
        this.text = text;
        this.font = font;
    }

    @Override
    public void handleEvent(Event event) {
        PdfDocumentEvent docEvent = (PdfDocumentEvent) event;
        PdfDocument pdfDoc = docEvent.getDocument();
        Painting painting = new Painting(pdfDoc, font);
        painting.drawHeader();
        painting.drawHeaderText(text);
        painting.close();
    }
}

在添加內容前添加相應事件,同時需要記得在不需要的時候移除

// 移除監聽器
pdf.removeEventHandler(PdfDocumentEvent.START_PAGE, headerTextEvent);

1.4.10. 添加目錄

我沒有找到itext7原生是否有目錄添加,根據我自己的需求,我用Table組件來實現了自定義目錄,由於我的PDF是用來打印的,所以我並沒有給目錄添加Link,也就是頁面跳轉,不過當你徹底理解了我的項目,我想這個需求實現也不難

  • 實現效果如下,隨着內容的增長,目錄自動增長

先說下遇到的困難,目錄顧明思意,必須要有內容才會有目錄,所以實際上目錄是最後添加的,但如果我們添加內容到最後再跳轉到前面的頁面來添加目錄,有三個問題:

  1. 目錄有幾頁如何知道?
  2. 目錄有幾頁不知道,如何知道內容在第幾頁?
  3. 由於目錄不確定,所以後續內容的頁碼其實也是不確定的,也就是說頁碼也不是一頁頁可以添加過去的

而經過實踐你會發現,我們不能夠回到前幾頁去修改已存在的頁面,因為會提示你已經flush了,不能修改。

這時我看到了movePage這個方法,也就是可以通過移動頁面,把目錄在內容之後生成,后再移動到前幾頁,但是頁碼還是不能修改,發現腦袋不夠想了只能用上屁股,靈光一閃,不能一遍生成為什麼不能二次渲染呢?於是研究讀取原pdf在原pdf上修改,二次渲染的時候填上頁碼及移動頁面,主要代碼如下,包括了讀取中間文件,移動目錄,添加每頁頁碼

PdfReader reader = null;
PdfWriter writer = null;
String inPath = getInPath();
try {
    reader = new PdfReader(new File(inPath));
    writer = new PdfWriter(new File(outPath));
} catch (IOException e) {
    e.printStackTrace();
}
PdfDocument pdf = new PdfDocument(reader, writer);
Document doc = new Document(pdf);
int startPage = 7;
int numberOfPages = pdf.getNumberOfPages();
for (int i = 0; i < catalogSize; i++) {
    pdf.movePage(numberOfPages, startPage);
}
String forbidPage = properties.getProperty("forbidPage");
for (int pageNumber = 1; pageNumber < numberOfPages + 1; pageNumber++) {

    if (pageNumber > 6 + catalogSize && pageNumber != 8 + catalogSize) {
        if (forbidPage != null && (pageNumber - catalogSize) >= Integer.parseInt(forbidPage)) {
            continue;
        }
        PageSize pageSize = pdf.getDefaultPageSize();
        doc.showTextAligned(new Paragraph(String.format("- %d -", pageNumber)), pageSize.getWidth() / 2, 30, pageNumber, TextAlignment.CENTER, VerticalAlignment.MIDDLE, 0);
    }
}

1.5. 總結

經過上述總結,我基本上把項目中的大多基本點和難點都概括進去了,初次用itext7寫PDF的同學基本會遇到的問題基本都在上述這些,不理解的就把項目下下來運行Main方法慢慢調試,理解透我這個項目,還有其它問題那基本只能翻官網了

項目Github: https://github.com/tzxylao/onegeno-itext-pdf
itext7官網:https://itextpdf.com/

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

台中搬家遵守搬運三大原則,讓您的家具不再被破壞!

台中搬家公司推薦超過30年經驗,首選台中大展搬家

“天眼”主動出擊 固體廢物無處遁形_台中搬家公司

※推薦台中搬家公司優質服務,可到府估價

台中搬鋼琴,台中金庫搬運,中部廢棄物處理,南投縣搬家公司,好幫手搬家,西屯區搬家

2020-11-18

台中搬家公司教你幾個打包小技巧,輕鬆整理裝箱!

還在煩惱搬家費用要多少哪?台中大展搬家線上試算搬家費用,從此不再擔心「物品怎麼計費」、「多少車才能裝完」

2020-11-18
分享到:
[打印]
字號:[大] [中] [小]

  近年來,我國非法傾倒、填埋、轉移固體廢物現象突出,嚴重威脅生態環境安全,並制約經濟社會的發展。然而,固體廢物傾倒、堆存、填埋具有隨機性和隱蔽性,還存在整治后重複傾倒的現象,給監管造成很大難度。

  面對固體廢物監管難題,生態環境部充分利用遙感技術,為科學精準治污送上“神助攻”。   在生態環境部開展的打擊固體廢物環境違法行為專項行動(“清廢行動2019”)中,衛星環境應用中心綜合運用無人機遙感、衛星遙感、地理信息、互聯網、數據庫等技術手段,參与排查、整治和清理等環節,充分發揮了衛星遙感高精度、高頻次、覆蓋範圍廣的技術優勢,讓固體廢物“盡收眼底”。   通過“清廢行動2019”,生態環境部構建了固廢排查整治遙感核實技術方法,建立了固體廢物遙感解譯標準,固化了固體廢物遙感解譯技術流程,建立了“衛星遙感+無人機遙感+固體廢物執法系統”的天空地一體化固體廢物點位遙感監管技術體系和固體廢物監管業務模式,保障了“清廢行動2019”專項行動的高效、有序實施。   
固體廢物遙感排查整治顯成效   在排查整治工作中,傳統的地面調查不僅難以全方位發現固體廢物問題,而且耗費大量人力和時間成本,效果不佳。而遙感技術具有覆蓋範圍大、時效性強、分辨率高等優勢,能夠有效彌補地面調查覆蓋面的不足。   在“清廢行動2019”專項行動中,衛星環境應用中心完成了長江經濟帶主要水系沿岸共103萬平方公里的固體廢物疑似點位解譯,監測範圍占整個長江經濟帶總面積的50%,為固體廢物現場執法提供了準確靶向;在整治與清理環節,完成了固體廢物問題點位整治進度遙感核實工作,節省了人工現場核實的成本。通過對比發現,遙感技術開展固體廢物解譯與核實所耗費的成本僅為人工成本的1/5。


長江經濟帶固體廢物分布圖   
構建天空地一體化監管模式   衛星應用中心研發的固體廢物執法系統(現場核實APP+信息管理系統),具備固體廢物非法傾倒點位的導航、定位、核實、填報、拍照、傳輸以及調查後點位的存儲、管理、統計等功能,實現固體廢物非法傾倒點位的綜合監控信息化管理,提升了固體廢物核實及整改的監管效率。同時,通過APP聯網直報的方式,改變了過去地方紙質填報和清單式填報排查信息的傳統工作模式,實現了固體廢物監管和執法全過程信息化、空間化,保證了信息填報的準確性和安全性。
固體廢物執法系統   
“三個準確”支撐監管效率   為確保排查整治精準有效,衛星環境應用中心用“三個準確”為排查整治工作保駕護航。一是準確核實固廢點位經緯度。通過對比遙感影像和現場照片,結合周邊地物信息,精確定位並核實固廢空間位置;二是準確判斷固廢整治情況。利用多時相高分辨率遙感影像,獲取固廢影像圖斑,結合圖斑的光譜、紋理和形狀等特徵,依據特徵距離,採用最小錯誤率法獲取影像變化閾值,得到不同特徵下的變化檢測結果,同時,基於固廢解譯標誌庫,輔以專家經驗對存疑點位二次判斷,確保遙感核實精度;三是準確下結論。綜合分析遙感判斷結果和現場排查記錄,得出最終整治結論,保障遙感核實的客觀性、準確性與科學性,極大提高了執法監管效率。   遙感技術在固體廢物監測與執法中的應用,充分將衛星遙感排查與人工地面核實相結合,不僅創新了固體廢物監測與執法技術手段,而且有效提升了固體廢物現場核實的工作效率,探索創建了固體廢物全過程監管新模式。

※推薦台中搬家公司優質服務,可到府估價

台中搬鋼琴,台中金庫搬運,中部廢棄物處理,南投縣搬家公司,好幫手搬家,西屯區搬家

Pixel 的雷達黑科技傳將被用在新世代 Google 智慧顯示器上_台中搬家

台中搬家公司費用怎麼算?

擁有20年純熟搬遷經驗,提供免費估價且流程透明更是5星評價的搬家公司

曾在 Google Pixel 旗艦機上作為新進手勢感應功能的關鍵感應器 Soli Motion 雷達感測器,來到了最新的 Pixel 5 上,卻疑似因為產品定位而沒有提供,更引起 Google 可能已經放棄這方面發展的猜測。不過現在又有了它可能會透過更多 Nest Home 裝置復活的跡象。繼續閱讀 Pixel 的雷達黑科技傳將被用在新世代 Google 智慧顯示器上報導內文。

▲圖片來源:Google

Pixel 的雷達黑科技傳將被用在新世代 Google 智慧顯示器上

其實在外媒去年訪談 Google 的時候,官方就有表示並沒有放棄 Soli 雷達技術。至於可能的應用方向,當時就有猜測很可能會被用在物聯產品方面 — 後續也真的先被 Nest 溫控器所採納。而隨著支援超音波偵測點亮的 Nest Home mini 推出之後,Google 似乎也打算要將更進階的手勢辨識功能給應用在更多的 Nest 物聯產品之上。

▲圖片來源:Google

相對於將 Soli Motion 感測器用在手機上,進行隔空用手勢切換音樂與關閉通知等用途 — 其實現在的智慧顯示器也已經可以透過攝影機來提供類似的手勢功能了。根據外媒 9to5Google 的消息,Google 2021 年 Smart Display 智慧顯示器,將很可能融入 Soli Motion 的雷達感應帶來更進階的機能,會將其應用在睡眠追蹤記錄功能。

誒… 雖然大家應該心裡第一反應就是「那我睡覺的資料不就讓OOO知道了」。不過與其擔心穿戴裝置是否會在睡眠過程中沒電,還有一定得要持續穿戴的麻煩。說真的,對在意這方面監測的使用者而言,透過隨時對著床並且不用擔心充電問題的 Google Home 物聯裝置,也算是解決了不少的麻煩 — 而且還能放放照片、播播音樂跟詢問問題(比讚)。

▲圖片來源:Google

是說,這也不是 Nest 首度採用 Soli 感應器了。其實在他們的自動溫控產品上,就已經有導入來做為更精確感應居家動靜的用途。講起來,這樣的技術好像在物聯產品上反而更發光發熱,創造出不少不錯的應用呢。感覺可以期待一下新世代 Smart Display 可以因此獲得什麼樣的有趣創新功能。

引用來源

台中搬家遵守搬運三大原則,讓您的家具不再被破壞!

台中搬家公司推薦超過30年經驗,首選台中大展搬家

延伸閱讀:

蘋果 AirTags 防丟追蹤器還沒出,但已有皮革鑰匙圈與眼鏡環三方配件照流出

沒錯 Facebook 又改版了,差在哪你看得出來嗎?

您也許會喜歡:

【推爆】終身$0月租 打電話只要1元/分

立達合法徵信社-讓您安心的選擇

台中搬家公司費用怎麼算?

擁有20年純熟搬遷經驗,提供免費估價且流程透明更是5星評價的搬家公司

Python驗證碼識別_台中搬家

台中搬家公司費用怎麼算?

擁有20年純熟搬遷經驗,提供免費估價且流程透明更是5星評價的搬家公司

項目地址:https://github.com/kerlomz/captcha_trainer

編譯版下載地址: https://github.com/kerlomz/captcha_trainer/releases/tag/v1.0

注意:若使用雲服務器 (Windows Server版) 遇到閃退,請按照步驟:我的電腦——屬性——管理——添加角色和功能——勾選桌面體驗,點擊安裝,安裝之後重啟即可。

2020/06/01編外:

想必各位只是偶然間搜到這篇文章,網上文章參差不齊,標題黨很多,能跑起來的開源代碼很少,對於能跑起來的代碼,也經常遇到以下問題如:內存泄漏,網絡參數寫死導致更換訓練集報錯,網絡跑其他樣本識別率低,沒有調用示例等等。

再往下看之前,我可以向你們保證,它絕對會是你所見過的所有驗證碼有關的文章中最實用,最接近生產水平的。

  1. 對小白: 你可以不需要動手寫任何一行代碼。
  2. 對小企業: 它的可用性和穩定性是經得起考驗的,在性能上也是同行領先的,可以放心入坑。

因為小編打算轉行了,離開這個行業之前總要留下點什麼證明自己來過,總有人和我說的這個部署不會調用,可能你們想要的是一行pip就搞定環境的,所以今天給你們安排了麻瓜OCR(MuggleOCR)。
https://pypi.org/project/muggle-ocr
它整合了簡單驗證碼識別通用模型+印刷文字通用識別,並且支持調用本文框架訓練的模型。調用只需要三行核心代碼:

import time
# STEP 1
import muggle_ocr
import os
# STEP 2
sdk = muggle_ocr.SDK(model_type=muggle_ocr.ModelType.OCR)
root_dir = r"./imgs"
for i in os.listdir(root_dir):
    n = os.path.join(root_dir, i)
    with open(n, "rb") as f:
        b = f.read()
    st = time.time()
    # STEP 3
    text = sdk.predict(image_bytes=b)
    print(i, text, time.time() - st)

這真的很簡單,應付一般的文字識別和驗證碼都足夠了。(文字識別過幾天會更新一下新模型,畢竟0601模型就跑了半天。

1. 前言

本項目適用於Python3.7,GPU>=NVIDIA GTX1050Ti,原master分支新增了GUI配置界面以及編譯版本了,是時候寫一篇新的文章了。

長話短說,開門見山,網絡上現有的代碼以教學研究為主,本項目是為實用主義者定製的,只要基本的環境安裝常識,便可很好的訓練出期望的模型,重定義幾個簡單的參數任何人都能使用深度學習技術訓練一個商業化成品。

筆者選用的時下最為流行的CNN+BLSTM+CTC(CRNN)進行端到端的不定長驗證碼識別,代碼中預留了CNNX(搜不到因為是小編自己拼湊的)/MobileNet/DenseNet121/ResNet50等選項,可以在配置界面中直接選用。首先,介紹個大概吧。

網格結構 predict-CPU predict-GPU 模型大小
CNN5+Bi-LSTM+H64+CTC 15ms 8ms 2mb
CNN5+CrossEntropy 8ms 2ms 1.5mb

H16/H64指的是Bi-LSTM的隱藏神經元個數UnitsNum,所以本項目使用GPU訓練,使用CPU進行預測。預測服務部署項目源碼請移步此處:https://github.com/kerlomz/captcha_platform
部署項目的編譯版下載地址:https://github.com/kerlomz/captcha_platform/releases

2.環境依賴:

花了超長篇幅介紹了訓練環境的基本搭建,主要是給尚未入門的讀者看的,老鳥們隨便跳過,若不希望在環境上面浪費時間的,歡迎使用編譯版,可在文章開頭找到下載地址。

關於CUDA和cuDNN版本的問題,不少人很糾結,這裏就列出官方通過pip安裝的TensorFlow的版本對應表:

Linux

Version Python version Compiler Build tools cuDNN CUDA
tensorflow_gpu-1.14.0 3.7 GCC 4.8 Bazel 0.15.0 7.6 9

Windows

Version Python version Compiler Build tools cuDNN CUDA
tensorflow_gpu-1.14.0 3.7 MSVC 2015 update 3 Bazel 0.15.0 7.6 10

如果希望使用上面對應之外的搭配的CUDA和cuDNN,可以自行編譯TensorFlow,或者去Github上搜索TensorFlow Wheel找到第三方編譯的對應版本的whl安裝包。提前預警,若是自己編譯將會苦難重重,坑很多,這裏就不展開了。

2.1 本項目環境依賴

目前在以下主流操作系統平台均測試通過:

操作系統 最低支持版本
Ubuntu 16.04
Windows 7 SP1
MacOS N/A

本訓練項目主要的環境依賴清單如下

依賴 最低支持版本
Python 3.7
TensorFlow-GPU 1.14.0
Opencv-Python 4.1.2.30
Numpy 1.16.0
Pillow 4.3.0
PyYaml 3.13
tqdm N/A

2.1.1 Ubuntu 16.04 下的 Python 3.7

1)先安裝Python環境(有Python 3.7環境的可以忽略)

sudo apt-get install openssl  
sudo apt-get install libssl-dev
sudo apt-get install libc6-dev gcc  
sudo apt-get install -y make build-essential zlib1g-dev libbz2-dev libreadline-dev $ libsqlite3-dev wget curl llvm tk-dev 
wget https://www.python.org/ftp/python/3.7.6/Python-3.7.6.tgz
tar -vxf Python-3.7.6.tar.xz
cd Python-3.7.6
./configure --prefix=/usr/local  --enable-shared
make -j8
sudo make install -j8

經過上面指令就安裝好Python3.7環境了,如果提示找不到libpython3.7m.so.1.0就到/usr/local/lib路徑下將該文件複製一份到/usr/lib和/usr/lib64路徑下。
2)安裝相關依賴(這一步Windows和Linux通用)
可以直接在項目路徑下執行pip3 install -r requirements.txt安裝所有依賴,注意這一步是安裝在全局Python環境下的,強烈建議使用虛擬環境進行項目間的環境隔離,如VirtualenvAnaconda等等。
我一般使用的是Virtualenv,有修改代碼需要的,建議安裝PyCharm作為Python IDE

virtualenv -p /usr/bin/python3 venv # venv is the name of the virtual environment.
cd venv/ # venv is the name of the virtual environment.
source bin/activate # to activate the current virtual environment.
cd captcha_trainer # captcha_trainer is the project path.
pip3 install -r requirements.txt

2.1.2 Ubuntu 16.04 下的 CUDA/cuDNN

網上看到過很多教程,我自己也部署過很多次,Ubuntu 16.04遇到的坑還是比較少的。14.04支持就沒那麼好,如果主板不支持關閉SecureBoot的話千萬不要安裝Desktop版,因為安裝好之後一定會無限循環在登陸界面無法進入桌面。
網上教程說要加驅動黑名單什麼的我直接跳過了,親測沒那個必要。就簡單的幾步:
1. 下載好安裝包
注意下載runfile類型的安裝包,deb安裝會自動安裝默認驅動,極有可能導致登陸循環
NVIDIA 驅動下載:https://www.geforce.cn/drivers
CUDA 下載地址:https://developer.nvidia.com/cuda-downloads
cuDNN 下載地址:https://developer.nvidia.com/cudnn (需要註冊NVIDIA賬號且登陸,下載deb安裝包)

2. 關閉圖形界面
Ctrl+alt+F1進入字符界面,關閉圖形界面

sudo service lightdm stop

3. 安裝Nvidia Driver

命令中的版本自己對應下載的版本改,在上面的下載地址根據自己的顯卡型號下載最新版,切記是runfile格式的安裝包。

sudo chmod a+x NVIDIA-Linux-x86_64-384.90.run //獲取執行權限
sudo ./NVIDIA-Linux-x86_64-384.90.run –no-x-check –no-nouveau-check –no-opengl-files //安裝驅動

安裝成功以後使用以下命令驗證,如果显示顯卡信息則表示安裝成功

nvidia-smi

4. 安裝CUDA

1)先安裝一些系統依賴庫

sudo apt-get install freeglut3-dev build-essential libx11-dev libxmu-dev libxi-dev libgl1-mesa-glx libglu1-mesa libglu1-mesa-dev
  1. 執行安裝程序,按指示無腦繼續就好了,如果提示是否安裝驅動選不安裝。
sudo sh cuda_9.0.176_384.81_linux.run

安裝完如果環境變量沒配上去,就寫到 ~/.bashrc 文件的尾部

export PATH=/usr/local/cuda-9.0/bin${PATH:+:${PATH}}
export LD_LIBRARY_PATH=/usr/local/cuda-9.0/lib64${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}

然後在終端執行 sudo ldconfig更新,安裝完畢就可以重啟機器重啟圖形界面了。

sudo service lightdm start

2.1.3 Windows 系統

在Windows其實簡單很多,只要到官網下載安裝包無腦安裝就可以了,下載連接同Ubuntu,先安裝Python,顯卡驅動,CUDA,然後下載對應的cuDNN替換到對應路徑即可。

3 使用

在訓練之前,有不少群友經常問我“訓練4位數英文数字需要多少樣本?”諸如此類的問題,我這裏統一做個回復,樣本數量主要是看樣本的特徵複雜度而定。

這裏可以提供幾個參考依據: 是否變形?是否旋轉?是否有複雜背景干擾?是否多種字體?字符集(分類數)多大?位數(標籤數)多少?

  1. 一般簡單的幾百個樣本(需要自行調整 驗證集大小驗證批次大小 )即可。
  2. 稍微複雜的幾千個樣本一般都能搞定。
  3. 特別複雜的幾萬樣本起。
  4. 中文這種幾千個分類的一般十萬起。

注:只準備一百個不到樣本的親們,千萬不要嘗試訓練測試,因為根本跑不起來。

入手的第一步環境搭建好了,那就是準備跑代碼了,還是有幾個必要的條件,巧婦難為無米之炊,首先,既然是訓練,要先有訓練集,有一個新手嘗鮮的訓練集,是mnist手寫識別的例子,可以在騰訊雲下載:https://share.weiyun.com/5pzGF4V
,現在萬事俱備,只欠東風。

3.1 定義一個模型

本項目基於參數化配置,不需要改動任何代碼,可以通過可視化界面操作訓練幾乎任何字符型圖片驗證碼。訓練框架界面可以大致劃分為幾個部分:

  1. Neural Network – 神經網絡區
  2. Project Configuration – 項目配置區
  3. Sample Source – 樣本源配置區
  4. Training Configuration – 訓練配置區
  5. Buttons – 功能控制區

依此類推的訓練配置的步驟如下:

  1. 神經網絡區 的配置項看起來很多,對於新手來說,可以直接使用默認的配置:CNNX+GRU+CTC+C1組合(CNN前置網絡+GRU+CTC+單通道)。
  2. 項目配置區 的配置項在網絡選好之後配置項目名,按回車或者點擊空白處確認。
  3. 樣本源配置區 的配置項用來配置樣本源的路徑,訓練樣本是根據此路徑進行打包成TFRecords格式,驗證樣本可以不指定,使用[Validation Set Num]參數隨機從訓練集總抽樣成驗證集。
  4. 訓練配置區 的配置項負責定義訓練完成的條件如:結束準確率,結束COST,結束Epochs,批次大小
  5. 功能控制區 的配置項,設置完上面步驟,先點擊[Make Dataset] 打包樣本,再點擊[Start Training]開始訓練。

以下部分有基礎的讀者們可以了解一下:

如若使用CrossEntropy作為解碼器需要注意標籤數LabelNum和圖片尺寸需要滿足的關係,因為網絡為多標籤而設計(一般的多標籤採用直接連接多個分類器),卷積層的輸出 outputs 經過了以下變換:

Reshape([label_num, int(outputs_shape[1] / label_num)])

為了保證運算 int(outputs_shape[1] / label_num) 能夠取得正整數,也意味着他們之間存在某種關係,對於CNN5+Cross Entropy的網絡結構,Conv2D層的步長皆為1,那麼需要保證以下關係成立:

\[mod(\frac{輸入寬度\times輸入高度\times輸出層參數}{池化步長^{池化層數}\times標籤數})= 0 \]

所以有時候需要Resize網絡輸入的Shape

網絡 池化步長^池化層數 輸出層參數
CNN5 16 64
CNNX 8 64
ResNet50 16 1024
DenseNet 32 2048

例如使用CNN5+CrossEntropy組合,則輸入寬度與輸入高度需要滿足:

\[mod(\frac{輸入寬度\times輸入高度\times64}{16\times標籤數})= 0 \]

台中搬家遵守搬運三大原則,讓您的家具不再被破壞!

台中搬家公司推薦超過30年經驗,首選台中大展搬家

同理如果CNN5+RNN+CTC,卷積層之後的輸出經過以下變換:

Reshape([-1, outputs_shape[2] * outputs_shape[3]])

原輸出(batch_size, outputs_shape[1], outputs_shape[2], outputs_shape[3]),RNN層的輸入輸出要求為(batch, timesteps, num_classes),為了接入RNN經過以上操作,那麼又引出一個Time Step的概念,所以timesteps的值也是 outputs_shape[1],而CTC Loss要求的輸入為 [batch_size, frames, num_labels],若是 timesteps 小於標籤數則無法計算損失,也就無法找損失函數中找到極小值,梯度何以下降。timesteps 最合理的值一般是標籤數的2倍,為了達到目的,也可以通過Resize網絡輸入的Shape解決,一般情況timesteps直接關聯於圖片寬度,大多情況只要按比例放大寬度即可。

ExtractRegex 參數:

注意:如果訓練集的命名格式和我提供的新手訓練集不一樣,請根據實際情況修改ExtractRegex的正則表達式。目前只支持在yaml配置文件中直接修改,尚未提供GUI界面修改的支持。 DatasetPath 和SourcePath參數允許多個路徑,這種操作適用於需要將多種樣本訓練為一個模型,或者希望訓練一套通用泛化模型的人。
字符集Category其實大多數情況下不需要修改,一般的圖形驗證碼離不開数字和英文,而且一般來說是大小寫不敏感的,不區分大小寫,因為打碼平台收集的訓練集質量參差不齊,有些大寫有些小寫,不如全部統一為小寫,默認ALPHANUMERIC_LOWER則會自動將大寫的轉為小寫,字符集可定製化很靈活,除了配置備註上提供的幾種類型,還可以訓練中文,自定義字符集用list表示,示例如下:

Category: ['常', '世', '寧', '慢', '南', '制', '根', '難']

如果是單標籤分類,可以配合LabelNum=1,例如:

Category: ["航母", "雨靴", "毛線", "安全帽", "調色板", "海鷗", "日曆", "網球拍", ......]

其文件名示例:航母_1231290424123.png

如果是多標籤分類,可以配合LabelSplit=&,例如:

Category: ["航母", "雨靴", "毛線", "安全帽", "調色板", "海鷗", "日曆", "網球拍", ......]

其文件名示例:航母&雨靴&毛線_1231290424123.png

可以自己根據收集訓練集的實際字符集使用率來定義,也可以無腦網上找3500常用字來訓練,注意:中文字符集一般比数字英文大很多,剛開始收斂比較慢,需要更久的訓練時間,也需要更多的樣本量,請量力而行

形如上圖的圖片能輕鬆訓練到95%以上的識別率。
ImageWidth、ImageHeight只要和當前圖片尺寸匹配即可,其實這裏的配置主要是為了方便後面的部署智能策略。

Pretreatment參數:

該參數是用來做圖片預處理的,例如形如以下的GIF動圖,

可以使用ConcatFrames參數選取幀對兩幀進行水平拼接,適用於處理滾動型GIF,而閃爍型GIF可以使用BlendFrames參數進行融合。

3.2 開始訓練

  1. 經過 採集標註樣本形如 xxx_隨機數.png
  2. 打包樣本
    通過GUI界面的 [Make Dataset] 或者 make_dataset.py 直接打包。
    注意:使用源碼運行本項目的功能模塊需要具備一定的語言基礎,參數修改的部分和示例已預留好,盡量不修改核心類或函數的代碼以免出現錯誤。

按照上面的介紹,配置只要修改極少數的參數對應的值,就可以開啟正式的訓練之旅了,具體操作如下:
可以直接使用 PyCharm 的 Run,執行 trains.py,也可以在激活Virtualenv下使用終端亦或在安裝依賴的全局環境下執行,但本文建議全程使用GUI界面進行操作,使用GUI僅需啟動 app.py 即可。

python3 trains.py

剩下的就是等了,看過程,等結果。
正常開始訓練的模樣應該是這樣的:

訓練結束會在項目的out路徑下生成一個包含pb文件的graph目錄和包含yaml文件的model目錄,下面該到部署環節了。

3.3 部署

真的很有必要認真的介紹一下部署項目,比起訓練,這個部署項目傾注了筆者更多的心血,為什麼呢?
項目地址:https://github.com/kerlomz/captcha_platform

如希望將本系統集成於自己的項目中的可以參考python-sdk的使用:
https://pypi.org/project/muggle-ocr/
該項目的核心基於 captcha_platform/sdk/pb/sdk.py 可以根據需要自行修改,抑或直接使用MuggleOCR 調用訓練框架生產的模型。(具體調用方法可點擊上面鏈接有對應的文檔介紹)

編譯版:https://github.com/kerlomz/captcha_platform/releases,使用編譯版無需安裝Python和TensorFlow環境。

真的值得了解的幾點

  1. 同時管理多個模型,支持模型熱拔插
  2. 靈活的版本控制
  3. 支持批量識別
  4. 服務智能路由策略

首先筆者重寫了TensorFlow的Graph會話管理,設計會話池,允許同時管理多模型,實現多模型動態部署方案。

1) 訓練好的 pb模型只要放在部署項目的graph路徑下,yaml模型配置文件放在model, 即可被服務發現並加載。(用SDK調用時,兩者置於同一目錄下)

2) 如果需要卸載一個正在服務的模型,只需要在model中刪除該模型的yaml配置文件,在graph中刪除對應的pb模型即可。

3) 如果需要更新一個已經服務中的模型,只需修改新版的模型yaml配置文件的版本號高於原模型的版本號,按先放pb後放yaml的順序,服務便會自動發現新版的模型並加載使用,舊的模型將因版本低於新版模型不會被調用,可以按照上述的卸載方法卸載已被棄用的模型釋放內存。
上面的操作中無需重啟服務,完全的無縫切換

其次,一套服務想要服務於各式各樣的圖像識別需求,可以定義一套策略,訓練時將所有尺寸一樣的圖片訓練成一個模型,服務根據圖片尺寸自動選擇使用哪個模型,這樣的設計使定製化和通用性共存,等積累到一定多樣的訓練集時可以將所有的訓練集合到一起訓練一個通用模型,亦可以彼此獨立,每個模型的疊加僅僅增加了少量的內存或顯存,網上的方案大多是不同的模型單獨部署一套服務,每個進程加載了一整套TensorFlow框架勢必是過於龐大和多餘的。

用到批量識別需求的人相對少很多這裏就不展開介紹了。但是這裏給出一個12306的例子:

FieldParam:
  CorpParams: [
    {
      "start_pos": [118, 0],
      "interval_size": [0, 0],
      "corp_num": [1, 1],
      "corp_size": [60, 30]
    },
    {
      "start_pos": [5, 40],
      "interval_size": [5, 5],
      "corp_num": [4, 2],
      "corp_size": [66, 66]
    }
  ]
  OutputCoord: True

該參數可以用於大圖的裁剪組成一批小圖作為一個批次的輸入,改用法可以避免多次調用。

但是識別項目提供了多套可選的服務有:gRPC,Flask,Tornado,Sanic,其中Flask和Tornado提供了加密接口,類似於微信公眾號開發接口的SecretKey和AccessKey接口,感興趣的可以在demo.py中閱讀調用源碼了解。

部署的使用可以經過package.py編譯為可執行文件,這樣可以免去更換機器環境安裝的煩惱,部署項目安裝流程同訓練項目,項目中提供的requirements.txt已經將所需的依賴都列清楚了,強烈建議部署項目安裝cpu版TensorFlow。

本項目部署推薦使用Tornado版,功能最齊全,性能最為穩定。

Linux:

  1. Tornado:
# 端口 19952
python3 tornado_server.py
  1. Flask
# 方案1,裸啟動, 端口 19951
python flask_server.py 
# 方案2,使用gunicorn,端口 5000
pip install gunicorn 
gunicorn -c deploy.conf.py flask_server:app
  1. Sanic:
# 端口 19953
python3 sanic_server.py
  1. gRPC:
# 端口 50054
python3 grpc_server.py
  1. 編譯版(基於Tornado)
# 前台運行
./captcha_platform_tornado
#後台運行
nohup ./captcha_platform_tornado &

Windows:
Windows平台下都是通過python3 xxx_server.py啟動對應的服務,注意,Tornado、Flask、Sanic的性能在Windows平台都大打折扣,gRPC是Google開源的RPC服務,有較為優越的性能。
編譯版直接運行編譯后的exe可執行文件即可。

3.4 調用/測試

1. Tornado服務:

請求地址 Content-Type 參數形式 請求方法
http://localhost:19952/captcha/v1 application/json JSON POST

具體參數:

參數名 必選 類型 說明
image Yes String Base64 編碼
model_name No String 模型名,yaml配置中可綁定
need_color No String 顏色過濾,black/red/blue/yellow/green/white
output_split No String 多標籤分割字符

請求為JSON格式,形如:{“image”: “base64編碼后的圖像二進制流”}

返回結果:

參數名 類型 說明
message String 識別結果或錯誤消息
code String 狀態碼
success String 是否請求成功

該返回為JSON格式,形如:{“message”: “xxxx”, “code”: 0, “success”: true}

2. Flask服務:

請求地址 Content-Type 參數形式 請求方法
http://localhost:19951/captcha/v1 application/json JSON POST

請求參數和返回格式同上

3. Sanic服務:

請求地址 Content-Type 參數形式 請求方法
http://localhost:19953/captcha/v1 application/json JSON POST

請求參數和返回格式同上

4. gRPC服務:
需要安裝依賴,grpcio、grpcio_tools和對應的grpc.proto文件,可以直接從項目中的示例代碼demo.py中提取。

python -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. ./grpc.proto

grpcio、grpcio_tools 是根據 grpc.proto 使用上述命令生成的。

class GoogleRPC(object):

    def __init__(self, host: str):
        self._url = '{}:50054'.format(host)
        self.true_count = 0
        self.total_count = 0

    def request(self, image, model_type=None, model_site=None):

        import grpc
        import grpc_pb2
        import grpc_pb2_grpc
        channel = grpc.insecure_channel(self._url)
        stub = grpc_pb2_grpc.PredictStub(channel)
        response = stub.predict(grpc_pb2.PredictRequest(
            image=image, split_char=',', model_type=model_type, model_site=model_site
        ))
        return {"message": response.result, "code": response.code, "success": response.success}

if __name__ == '__main__':
    result = GoogleRPC().request("base64編碼后的圖片二進制流")
    print(result)

3.5 奇技淫巧

該項目還可以直接用於識別帶顏色的驗證碼,部署項目middleware/impl/color_extractor.py基於k-means實現了顏色分離模塊,可用於處理如下形式的驗證碼:

還有一種方案是同時預測驗證碼和每個字符對應的顏色,不過這需要修改現有的神經網絡進行支持,在最後一層修改為雙輸出,一個輸出顏色,一個輸出對應字符,這對於樣本標註的要求較高,也提高的成本,所以如果能用無限生成樣本,那問題就迎刃而解了,比如上圖,筆者就寫了樣本生成代碼,感興趣的可以移步:
https://www.jianshu.com/p/da1b972e24f2
其實還有很多很多技巧,例如,用生成的樣本代替訓練集,其實網上的圖片驗證碼大多是採用開源的,稍作修改而已,大多數情況都能被近似生成出來,上述展示的驗證碼圖片不代表任何實際的網站,如有雷同,純屬巧合,該項目只能用於學習和交流用途,不得用於非法用途。

後記

如果文章描述不夠詳盡或需要技術支持的,可以加群 857149419 諮詢,或在開源項目中提issue,很榮幸能為開源社區貢獻綿薄之力。

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

台中搬家公司費用怎麼算?

擁有20年純熟搬遷經驗,提供免費估價且流程透明更是5星評價的搬家公司

全球6.9億人陷饑餓危機 UN:疫情加劇惡化速度_台中搬家

台中搬家公司費用怎麼算?

擁有20年純熟搬遷經驗,提供免費估價且流程透明更是5星評價的搬家公司

摘錄自2020年7月14日中央社羅馬綜合外電報導

聯合國今天(14日)發表統計報告,全球每九人即有一人受飢餓所苦,疫情使全球飢餓問題更加惡化。法新社報導,全球經濟趨緩加上氣候變遷衝擊,全球更多人陷入飢餓。許多人無法負擔營養的食物,營養不足情形加劇,肥胖人口也日益增加。研究顯示,低品質飲食會導致嚴重的「健康與環境負面影響」。

聯合國2020年「世界糧食安全和營養狀況」(The State of Food Security and Nutrition in the World)年度報告指出:「數十年以來,飢餓人口原本穩定下降中,但2014年又開始緩緩回升。」

台中搬家遵守搬運三大原則,讓您的家具不再被破壞!

台中搬家公司推薦超過30年經驗,首選台中大展搬家

經調查發現,全球近6億9000萬人陷於飢餓,佔全球人口8.9%,光是2019年就增加了1000萬飢餓人口,與五年前相比更多了6000萬人。若目前的趨勢持續,五年前設定的「2030年以前消除饑餓」目標不可能實現。

據聯合國估計,2030年以前,世界上超過8億9000萬人會受飢餓影響(全球人口9.8%)。

土地利用
國際新聞
全球
糧食危機
飢餓
營養不良
疫情下的社會衝突
人口
糧食

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

台中搬家公司費用怎麼算?

擁有20年純熟搬遷經驗,提供免費估價且流程透明更是5星評價的搬家公司

疑似 2021 iPad Pro CAD 工程圖現身,外型改變不大,主要更新在內部硬體_台中搬家

台中搬家遵守搬運三大原則,讓您的家具不再被破壞!

台中搬家公司推薦超過30年經驗,首選台中大展搬家

近年 Apple 更新旗下產品的時間可說逐漸縮短,也因此對於想買新品的人,一定會期待今年會不會有新機種出現?該這時候買還是等等看?去年就曾更新過的 iPad Pro,照道理來說今年應該不太可能有新款(上一次是二年一更),但稍早網路上出現一系列疑似 2021 iPad Pro CAD 工程圖,加上先前分析師的預測內容,看來今年也是蠻有機會的。

疑似 2021 iPad Pro CAD 工程圖現身

稍早外媒 mysmartprice 獲得一組 2021 iPad Pro CAD 洩漏工程圖,而且還註明是從值得信賴的內部人士提供。

圖中明顯顯示,2021 iPad Pro  外型不會有太大的改變,基本上長得一樣,但有可能會更改內部的揚聲器,進而減少喇叭孔數量。mysmartprice  也表示,目前已經確認 11 吋 iPad Pro 的尺寸,將會是 245.74 x 176.61 x 5.90mm,厚度則跟上一代相同:

鏡頭模組看起來也跟上一代一樣,不過似乎又凸出來一點,至於相機規格目前都還不知道。音量鍵將位於右側,鎖定鍵則是頂部,同樣會採用 USB-C 的傳輸充電介面:

硬體方面,既然是新款 2021 iPad Pro,搭載 A 系列晶片的效能當然有望大幅提升。先前知名分析師還指出,Apple 將會發表 mini-LED 版本的 12.9 吋 iPad Pro,厚度可能會增加 0.5mm。

此外,台灣 DigiTimes 去年也獲得內部人士提供的消息,2021 高端的 iPad 產品有機會獲得 mmWave 技術,意味著將支援 5G 網路。

台中搬家公司費用怎麼算?

擁有20年純熟搬遷經驗,提供免費估價且流程透明更是5星評價的搬家公司

2021 iPad Pro 推出時間預計會在今年 3 月,不過一切還是要以 Apple 為主。

資料來源:mysmartprice

最多樣好用的 iPad 手寫筆選擇 Kamera Pencil 開箱體驗(評價 / 評測 / 動手玩)

您也許會喜歡:

【推爆】終身$0月租 打電話只要1元/分

立達合法徵信社-讓您安心的選擇

台中搬家遵守搬運三大原則,讓您的家具不再被破壞!

台中搬家公司推薦超過30年經驗,首選台中大展搬家

apt-key 密鑰管理,apt-secure 原理 驗證鏈 驗證測試_網頁設計公司

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!

以設計的實用美學觀點,規劃出舒適、美觀的視覺畫面,有效提昇使用者的心理期待,營造出輕鬆、愉悅的網站瀏覽體驗。

apt-key

用於管理Debian Linux系統中的軟件包密鑰。每個發布的deb包,都是通過密鑰認證的,apt-key用來管理密鑰。

  • apt-key list

    列出已保存在系統中key。包括 /etc/apt/trusted.gpg/etc/apt/trusted.gpg.d/目錄下的密鑰

  • apt-key add <keyname >

    把下載的key添加到本地trusted數據庫中,使用描述性名稱,以gpg或asc作為文件擴展名

  • apt-key del <keyname>

    從本地trusted數據庫刪除key。

  • apt-key update (棄用,直接刪除和添加)

    更新本地trusted數據庫,刪除過期沒用的key。

  • apt-key adv --recv-key

    下載並添加到受信任密鑰環中(不做任何檢查,有風險)

    http://manpages.ubuntu.com/manpages/bionic/en/man8/apt-key.8.html

目錄、文件

/var/cache/apt/archives

已經下載到的.deb軟件包都放在這裏(用 apt-get install 安裝軟件時,軟件包的臨時存放路徑)

/var/lib/apt/lists

存放已安裝和未安裝的軟件列表

使用apt-get update命令會從/etc/apt/sources.list指定的源更新軟件列表,並保存到該目錄

/etc/apt

sources.list 官方軟件源地址(配置為阿里源)

souces.list.d 目錄下是第三方軟件源地址,裏面的文件必須以.list結尾

https://askubuntu.com/a/82844

/etc/apt

trusted.gpg: local trusted keys, new keys will be added here

trusted.gpg.d:additional keyrings can be stored here (by other packages or the administrator)

/usr/bin/

通過 apt 安裝的軟件,命令存放在 /usr/bin/ 目錄下

apt-secure

參考

http://manpages.ubuntu.com/manpages/bionic/en/man8/apt-secure.8.html

SecureApt

基礎元素

Release 文件

Release文件包含分發元數據和索引文件的校驗值

apt 要求隨 Release 文件一起發布一個 Relesase.gpg 的簽名文件,用來驗證安裝包提供者的信息

InRelease 文件

InRelease文件內聯gpg簽名(數據和簽名在一個 InRelease 文件中)

lfp@legion:/var/lib/apt/lists$ ls
...
# 兩個文件
deb.nodesource.com_node%5f12.x_dists_bionic_InRelease
deb.nodesource.com_node%5f12.x_dists_bionic_main_binary-amd64_Packages
...
# 三個文件
dl.google.com_linux_chrome_deb_dists_stable_main_binary-amd64_Packages
dl.google.com_linux_chrome_deb_dists_stable_Release
dl.google.com_linux_chrome_deb_dists_stable_Release.gpg
...

區別:在下載時避免競爭情況

The only difference to Release is that the signature is not detached, but within the file. This is a first step towards getting rid of race conditions when updating Packages/Sources files and mirror updates
running

https://lists.debian.org/debian-devel-announce/2009/11/msg00001.html

校驗值MD5

保護apt安全的基礎

debian archive 包含一個Release文件,隨安裝包一起更新,裡面包含了分發元數據和Package的MD5

Package文件里包含安裝信息以及安裝文件的MD5

驗證鏈

1)驗證簽名文件

簽名文件用來保證Package文件的正確性

  • 如果無法下載 Release 文件或 Release.gpg 簽名無效,則報錯

    W: GPG 錯誤……下列簽名無效 EXPKEYSIG……

    E: 倉庫……沒有数字簽名

    N: 無法安全地用該源進行更新,所以默認禁用該源

    缺少公鑰

  • apt 使用 gpg 來驗證簽名文件

    1. 獲取密鑰

      默認情況下,Debian 系統會預先安裝一些 Debian Archieve 的公鑰,保存在 /etc/apt/trusted.gpg文件中,第三方軟件密鑰需要通過apt-key add [.gpg] 安裝到/etc/apt/sources.list.d/目錄下

      一旦將密鑰添加到apt的密鑰環中,就相當於告訴apt信任該密鑰簽名的一切東西

      如果公鑰丟失,可以通過下面的命令到公鑰服務器上尋找

      apt-key adv --keyserver <server_url> --recv-key <keyId>

      1. 如果更新失敗可能是防火牆端口問題,嘗試指定常規HTTP端口80

      2. 如果連接的是公司的代理服務器,可以嘗試下面的方法

         --keyserver-options http-proxy=<myProxy> --keyserver keyserver.ubuntu.com
        
    2. 通過gpgv簽名驗證工具來驗證簽名的有效性

      詳細介紹參見博文GPG配置、命令、實例與apt-key密鑰測試

      • gpgv 認為apt密鑰環中的密鑰都是可信的,不會檢查其是否過期或被吊銷

      • 通過--keyring [.gpg file]指定密鑰環,-v可以显示更多信息

        apt 密鑰環保存在 /etc/apt/trusted.gpg 或 /etc/apt/trusted.gpg.d/xxx.gpg 中

      • 單獨簽名驗證

        gpgv --keyring /etc/apt/trusted.gpg [Release.gpg file] [Release file]

      • 內聯簽名驗證

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

        網站的第一印象網頁設計,決定了客戶是否繼續瀏覽的意願。台北網動廣告製作的RWD網頁設計,採用精簡與質感的CSS語法,提升企業的專業形象與簡約舒適的瀏覽體驗,讓瀏覽者第一眼就愛上它。

        gpgv --keyring /etc/apt/trusted.gpg [InRelease file]

2)驗證Package文件

Package 文件中包含軟件不同版本的信息,用來保證deb文件的正確性

  1. 從Release文件或InRelease文件中提取Package文件的MD5

    sed -n "s,main/binary-amd64/Packages$,,p" [Release / InRelease file]

  2. 計算Package文件的MD5

    md5sum [Packages file]

3)驗證安裝包

  1. 從Package文件中提取deb文件的MD5

    sed -n "s/MD5sum: //p" [Packages file]

  2. 從apt緩存中提取軟件的MD5

    apt-cache show [package_name] | sed -n "s/MD5sum: //p"

  3. 計算本地已下載deb文件的MD5

    md5sum [.deb file]

驗證測試

chrome 驗證

特點

  1. chrome 是Release文件和簽名文件[.gpg]分離的
  2. 使用本地密鑰環驗證(保存在 /etc/apt/trusted.gpg)

官方聲明

https://www.google.com/linuxrepositories/

Release.gpg文件

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1

iQIcBAABCAAGBQJeqbVjAAoJEHi9ZUc8s70TgUIP/RzWWeDxvtGrmLoWt0csiD+O
wrAr86yDSSzFasjKPcS+SQzs5FnCamFdTT7KD2C6thwRgCLR3oumHMuKC5hnb9/4
GP7qMCDYQEMR2IQcWfKPoT2fAX1eKDKJtv5qsAEdSb3uIW27zkdvUA4j4N6w4toA
RA24VV/VSK1p3T4j3HQzN6fOta0wA3onN9bPrcXZAig7Tm78SKbjYEzd1jxIeQQE
aTKP6AfHPnn8UFNkVyifigsd1Usaex3BJumzHq+jLhTtJDcLjqQNQdcKs48xY0Ek
lZJHY1w/p8e06Y16fXxO/Mh6+Kmu+ZBOKEo3VjshBOISASkMXG/JPEjWadP62A8S
lprRALXaWLcF5P5RYjdqhatCxH37SQr3iqqQmdC/PSCDq/Z5cYiVIElyUeHnMZ6i
X6wYvOd1n9p64VgUAINpbY0NeWZc0Kj1pMXaL+bohUnH8YWDfIhFdQDdQbd0DxBY
xgSTAuUn4DkMKZvtqVEsAIZk5VrYjWykdvdaZad8DdAhVxuHzl1xVEXRDyDhxvUN
IE2oOMv1N5MrXKHtGJLITlv0SAtbZRSaez91dudr9eoln8bZ+oFI9VrHO0xKO2/W
/VRMExkQC51OHCEtZKfsqqSAEG0sctvagq5MElCElZkmD/P72MuznRBgjbfeKs/B
JMSaAmp1mus5Mo7BZND6
=/bSj
-----END PGP SIGNATURE-----                      
驗證簽名
lfp@legion:/var/lib/apt/lists$ gpgv --keyring /etc/apt/trusted.gpg dl.google.com_linux_chrome_deb_dists_stable_Release.gpg dl.google.com_linux_chrome_deb_dists_stable_Release
gpgv: 簽名建立於 2020年04月30日 星期四 01時12分03秒 CST
gpgv:                使用 RSA 密鑰 78BD65473CB3BD13
gpgv: 完好的簽名,來自於“Google Inc. (Linux Packages Signing Authority) <linux-packages-keymaster@google.com>”

Release文件

包含Package文件的MD5

Origin: Google LLC
Label: Google
Suite: stable
Codename: stable
Version: 1.0
Date: Wed, 29 Apr 2020 17:11:57 UTC
Architectures: amd64
Components: main
Description: Google chrome-linux software repository
MD5Sum:
 2e55673e5a00d8837090d0922e198520 4599 main/binary-amd64/Packages
 eafbe9cc415e53d2280c86a0d64be27d 1133 main/binary-amd64/Packages.gz
 156e5ea7a0c6bed5973a68a45e546dc9 151 main/binary-amd64/Release
SHA1:
 9525687fab2b772c511c9e9ae5c7c7b6d8b92e2a 4599 main/binary-amd64/Packages
 c364469ff8578e7c7323b030ad3e459b9192a4ea 1133 main/binary-amd64/Packages.gz
 0f4348c2d4d7cc1f8e59b5934d87f1ca872f6e34 151 main/binary-amd64/Release
SHA256:
 667d27f55652d51c57c0eaab074dd2d365e373ebd5b6e1277b18606cc5177c1b 4599 main/binary-amd64/Packages
 7dc589a54517f36e7786b101555e9f1d2c6e2058b1b3743c575eb8c165094620 1133 main/binary-amd64/Packages.gz
 c1e3c9318381862306adcdc4fd4fe2d85be8aa4c4f3dcbb40fce80413f588286 151 main/binary-amd64/Release

提取Package文件的MD5
lfp@legion:/var/lib/apt/lists$ sed -n "s,main/binary-amd64/Packages$,,p" dl.google.com_linux_chrome_deb_dists_stable_Release
 2e55673e5a00d8837090d0922e198520 4599 
 9525687fab2b772c511c9e9ae5c7c7b6d8b92e2a 4599 
 667d27f55652d51c57c0eaab074dd2d365e373ebd5b6e1277b18606cc5177c1b 4599 

計算Package文件的MD5
lfp@legion:/var/lib/apt/lists$ md5sum dl.google.com_linux_chrome_deb_dists_stable_main_binary-amd64_Packages 
2e55673e5a00d8837090d0922e198520  dl.google.com_linux_chrome_deb_dists_stable_main_binary-amd64_Packages

Package文件可信

2e55673e5a00d8837090d0922e198520 一致

Package文件

包含deb文件的MD5

# 包含各種版本的chrome
Package: google-chrome-beta
...
Package: google-chrome-stable
Version: 81.0.4044.129-1
Architecture: amd64
Maintainer: Chrome Linux Team <chromium-dev@chromium.org>
Installed-Size: 229948
Pre-Depends: dpkg (>= 1.14.0)
Depends: ca-certificates, fonts-liberation, libappindicator3-1, libasound2 (>= 1.0.16), libatk-bridge2.0-0 (>= 2.5.3), libatk1.0-0 (>= 2.2.0), libatspi2.0-0 (>= 2.9.90), libc6 (>= 2.16), libcairo2 (>= 1.6.0), libcups2 (>= 1.4.0), libdbus-1-3 (>= 1.5.12), libdrm2 (>= 2.4.38), libexpat1 (>= 2.0.1), libgbm1 (>= 8.1~0), libgcc1 (>= 1:3.0), libgdk-pixbuf2.0-0 (>= 2.22.0), libglib2.0-0 (>= 2.39.4), libgtk-3-0 (>= 3.9.10), libnspr4 (>= 2:4.9-2~), libnss3 (>= 2:3.22), libpango-1.0-0 (>= 1.14.0), libpangocairo-1.0-0 (>= 1.14.0), libx11-6 (>= 2:1.4.99.1), libx11-xcb1, libxcb-dri3-0, libxcb1 (>= 1.6), libxcomposite1 (>= 1:0.3-1), libxcursor1 (>> 1.1.2), libxdamage1 (>= 1:1.1), libxext6, libxfixes3 (>= 1:5.0), libxi6 (>= 2:1.2.99.4), libxrandr2 (>= 2:1.2.99.3), libxrender1, libxss1, libxtst6, wget, xdg-utils (>= 1.0.2)
Recommends: libu2f-udev, libvulkan1
Provides: www-browser
Priority: optional
Section: web
Filename: pool/main/g/google-chrome-stable/google-chrome-stable_81.0.4044.129-1_amd64.deb
Size: 67137920
SHA256: fe140112304b243240a5f6b287105fd5b7d6e48c6ff682194a62c8d08fd0ed5b
SHA1: f5f984d1a1419b803a7a26dbda1d04fb8313c4b3
# md5
MD5sum: 3705bb8b32a9b4cfcc4440c14966acbc
Description: The web browser from Google
 Google Chrome is a browser that combines a minimal design with sophisticated technology to make the web faster, safer, and easier.

Package: google-chrome-unstable
...
提取deb文件的MD5
lfp@legion:/var/lib/apt/lists$ sed -n "s/MD5sum: //p" dl.google.com_linux_chrome_deb_dists_stable_main_binary-amd64_Packages 
9c6634a7bbda0cedb2d218410c0a06c2
3705bb8b32a9b4cfcc4440c14966acbc
fe9bc72b7cb12549a69187c0e393f930
從apt緩存中提取chrome信息
lfp@legion:/var/lib/apt/lists$ apt-cache show chromium-browser | sed -n "s/MD5sum: //p"
# 沒有匹配的md5,打開瀏覽器,查看chrome的版本信息是:版本 81.0.4044.129(正式版本) (64 位)
# apt-cache show chromium-browser 显示信息如下,沒有找到同一個版本,於是從Google下載了一個最新的安裝包
# Package: chromium-browser
# Filename: pool/universe/c/chromium-browser/chromium-browser_80.0.3987.163-0ubuntu0.18.04.1_amd64.deb
6dcd58431410a691c847a709765f7248
dfd394ff98654f1e0a97d204f7343ab1
計算deb文件的MD5

從Google那裡下載了一個deb安裝包

lfp@legion:~/Downloads$ md5sum google-chrome-stable_current_amd64.deb 
3705bb8b32a9b4cfcc4440c14966acbc  google-chrome-stable_current_amd64.deb
deb文件可信

3705bb8b32a9b4cfcc4440c14966acbc 一致

nodejs驗證

特點

  1. nodejs 是InRelease文件,內聯簽名
  2. 使用本地密鑰環驗證(保存在 /etc/apt/trusted.gpg)

InRelease文件

包含Package文件的MD5

驗證簽名
lfp@legion:/var/lib/apt/lists$ gpgv --keyring /etc/apt/trusted.gpg deb.nodesource.com_node%5f12.x_dists_bionic_InRelease 
gpgv: 簽名建立於 2020年04月30日 星期四 00時53分13秒 CST
gpgv:                使用 RSA 密鑰 9FD3B784BC1C6FC31A8A0A1C1655A0AB68576280
gpgv: 完好的簽名,來自於“NodeSource <gpg@nodesource.com>”

lfp@legion:/var/lib/apt/lists$ vim deb.nodesource.com_node%5f12.x_dists_bionic_InRelease

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

Origin: Node Source
Label: Node Source
Codename: bionic
Date: Wed, 29 Apr 2020 16:53:13 UTC
Architectures: i386 amd64 armhf arm64
Components: main
Description: Apt Repository for the Node.JS 12.x Branch
MD5Sum:
 d41d8cd98f00b204e9800998ecf8427e 0 main/binary-i386/Packages
 7029066c27ac6f5ef18d660d5741979a 20 main/binary-i386/Packages.gz
 cf52b42ebdc37bfabc86a5db93fcbdbc 130 main/binary-i386/Release
 # amd64
 6d2cd675d3c647d51a8ee0349754a976 1195 main/binary-amd64/Packages
 608cc59026b960ec64b97bcbeaa68003 765 main/binary-amd64/Packages.gz
 049fa528953b36ae91d8fe360618d46f 131 main/binary-amd64/Release
 14ce3c619a83d518ee3e433dedbdf26a 1216 main/binary-armhf/Packages
 219c6a1d7d300d409d4bb8249911d58f 775 main/binary-armhf/Packages.gz
 8064ccb91382a3c1cbade0c462ee18b3 131 main/binary-armhf/Release
 45ad97bad6053d65a462c352219fa962 1195 main/binary-arm64/Packages
 8afb33e583bf54aabaeb9b3378c3ca26 766 main/binary-arm64/Packages.gz
 670d019ad65bf455298c252afc334bff 131 main/binary-arm64/Release
 d41d8cd98f00b204e9800998ecf8427e 0 main/source/Sources
 7029066c27ac6f5ef18d660d5741979a 20 main/source/Sources.gz
 e4627d3fe224f8b3c07d9a69c88bedd2 132 main/source/Release

提取Package文件的MD5
sed -n "s,main/binary-amd64/Packages$,,p" deb.nodesource.com_node%5f12.x_dists_bionic_InRelease 
 6d2cd675d3c647d51a8ee0349754a976 1195 
 4615cf89691b8c95c052a84b09a1d24079268403 1195 
 8ec2d3674dc82a29ca759a2cf59cfe67a2b6c3a42106c523b11f93791a1e538e 1195 
計算Package文件的MD5
lfp@legion:/var/lib/apt/lists$ md5sum deb.nodesource.com_node%5f12.x_dists_bionic_main_binary-amd64_Packages 
6d2cd675d3c647d51a8ee0349754a976  deb.nodesource.com_node%5f12.x_dists_bionic_main_binary-amd64_Packages
Package文件可信

6d2cd675d3c647d51a8ee0349754a976 一致

Package文件

包含deb文件的MD5

Package: nodejs
Version: 12.16.3-1nodesource1
Architecture: amd64
Maintainer: Chris Lea <chl@nodesource.com>
Installed-Size: 87857
Depends: libc6 (>= 2.17), libgcc1 (>= 1:3.4), libstdc++6 (>= 4.8), python-minimal, ca-certificates
Conflicts: nodejs-dev, nodejs-legacy, npm
Replaces: nodejs-dev (<= 0.8.22), nodejs-legacy, npm (<= 1.2.14)
Provides: nodejs-dev, nodejs-legacy, npm
Homepage: https://nodejs.org
Priority: optional
Section: web
Filename: pool/main/n/nodejs/nodejs_12.16.3-1nodesource1_amd64.deb
Size: 17989662
SHA256: b2d1a6327f5a34c097d7fb5eeed8357d9758c09b30e356f45dfa01cc24103108
SHA1: de90a1776ee9995b3121ab68f49fef3cb110ce65
MD5sum: 9f87646d2782a572da1f965cf96f974f
Description: Node.js event-based server-side javascript engine
 Node.js is similar in design to and influenced by systems like
 Ruby's Event Machine or Python's Twisted.
 .
 It takes the event model a bit further - it presents the event
 loop as a language construct instead of as a library.
 .
 Node.js is bundled with several useful libraries to handle server tasks :
 System, Events, Standard I/O, Modules, Timers, Child Processes, POSIX,
 HTTP, Multipart Parsing, TCP, DNS, Assert, Path, URL, Query Strings.

提取deb文件的MD5
lfp@legion:/var/lib/apt/lists$ sed -n "s/MD5sum: //p" deb.nodesource.com_node%5f12.x_dists_bionic_main_binary-amd64_Packages 
9f87646d2782a572da1f965cf96f974f
從apt緩存中提取nodejs信息
lfp@legion:/var/lib/apt/lists$ apt-cache show nodejs | sed -n "s/MD5sum: //p"
# 包含不同版本的信息
9f87646d2782a572da1f965cf96f974f
0e6643fbe872255dbfaebd5449813d8f
02d7a42a30a7d72b78d9bc4a7ceb5a5a
3930b41c309e69cc0bd3737cfc1e7d31
計算deb文件的md5
lfp@legion:/var/lib/apt/lists$ md5sum /var/cache/apt/archives/nodejs_12.16.3-1nodesource1_amd64.deb 
9f87646d2782a572da1f965cf96f974f  /var/cache/apt/archives/nodejs_12.16.3-1nodesource1_amd64.deb
deb文件可信

9f87646d2782a572da1f965cf96f974f 一致

smplayer 驗證

特點

  1. smplayer 是InRelease文件,內聯簽名
  2. 使用第三方密鑰環去驗證(保存在/etc/apt/trusted.gpg.d目錄中)

驗證流程

  1. 簽名

    lfp@legion:/var/lib/apt/lists$ gpgv --keyring /etc/apt/trusted.gpg.d/rvm_ubuntu_smplayer.gpg ppa.launchpad.net_rvm_smplayer_ubuntu_dists_bionic_InRelease 
    gpgv: 簽名建立於 2020年04月13日 星期一 23時45分47秒 CST
    gpgv:                使用 RSA 密鑰 A7E13D78E4A4F4F4
    gpgv: 完好的簽名,來自於“Launchpad PPA named smplayer for rvm”
    
  2. Package

    MD5 7aa109a3525c661e783e9b943e4b46fa

    lfp@legion:/var/lib/apt/lists$ sed -n "s,main/binary-amd64/Packages$,,p" ppa.launchpad.net_rvm_smplayer_ubuntu_dists_bionic_InRelease 
     7aa109a3525c661e783e9b943e4b46fa             2909 
     29ca94a4f3a57c328b31789bce66cd6bbaa819e2             2909 
     6586e6ef8389cddb47ae0f7f7761ddbfedab35ed3ffbb3b10b4a1f91264577ae             2909 
    
    lfp@legion:/var/lib/apt/lists$ md5sum ppa.launchpad.net_rvm_smplayer_ubuntu_dists_bionic_main_binary-amd64_Packages 
    7aa109a3525c661e783e9b943e4b46fa  ppa.launchpad.net_rvm_smplayer_ubuntu_dists_bionic_main_binary-amd64_Packages
    
  3. deb

    MD5 601afc2fe220b608acb1e5b920afca96

    lfp@legion:/var/lib/apt/lists$ sed -n "s/MD5sum: //p" ppa.launchpad.net_rvm_smplayer_ubuntu_dists_bionic_main_binary-amd64_Packages 
    601afc2fe220b608acb1e5b920afca96
    b569cc540016f0b04fae5dd15a1434eb
    4eb1111c66b5087e7489cf7526321a9e
    45a466ca713b566f920d9e6414212552
    
    lfp@legion:/etc/apt/trusted.gpg.d$ apt-cache show smplayer | grep -E 'MD5|Filename'
    Filename: pool/main/s/smplayer/smplayer_20.4.2-1~bionic1_amd64.deb
    MD5sum: 601afc2fe220b608acb1e5b920afca96
    Filename: pool/universe/s/smplayer/smplayer_18.2.2~ds0-1_amd64.deb
    MD5sum: 7fdfc2f64d835cf5f7a38035523379a2
    
    lfp@legion:/var/cache/apt/archives$ md5sum smplayer_20.4.2-1~bionic1_amd64.deb 
    601afc2fe220b608acb1e5b920afca96  smplayer_20.4.2-1~bionic1_amd64.deb
    

沒有公鑰或簽名無效測試

  1. 本地沒有該公鑰

  2. 本地公鑰過期

    猜測:此時軟件發布者應該會創建一個新的子密鑰來簽名,而本地公鑰是過期的,情況類似於用一個錯誤的密鑰驗證簽名文件

    # 使用錯誤的密鑰去驗證簽名文件
    lfp@legion:~$ gpgv --keyring /etc/apt/trusted.gpg.d/sogou-archive-keyring.gpg /var/lib/apt/lists/typora.io_linux_._InRelease 
    gpgv: 簽名建立於 2020年03月04日 星期三 00時11分02秒 CST
    gpgv:                使用 RSA 密鑰 4AC441BE68B4ADAB7439FBF9BA300B7755AFCFAE
    gpgv:                issuer "abner@typora.io"
    gpgv: 無法檢查簽名:沒有公鑰
    

相關問題

EXPKEYSIG 沒有数字簽名

問題:執行apt update 出現如下錯誤

W: GPG 錯誤:https://dl.yarnpkg.com/debian stable InRelease: 下列簽名無效: EXPKEYSIG 23E7166788B63E1E Yarn Packaging yarn@dan.cx
E: 倉庫 “https://dl.yarnpkg.com/debian stable InRelease” 沒有数字簽名。
N: 無法安全地用該源進行更新,所以默認禁用該源

原因:

安裝第三方軟件的時候會同時安裝軟件倉庫地址以及密鑰,上述問題是因為本地的密鑰過期了,需要更新

https://github.com/yarnpkg/yarn/issues/7866#issue-558663837

辦法:更新密鑰

  1. 找到該軟件安裝方法中添加密鑰的方式(如yarn的安裝步驟一),再次執行即可

  2. 直接搜索密鑰添加到密鑰列表

    apt-key adv --keyserver <server_url> --recv-key <keyId>
    
  3. 到服務器找密鑰手動安裝

    1. 獲取 pub_key的ID

      23E7166788B63E1E

    2. 到密鑰服務器上以十六進制形式搜索

      http://keyserver.ubuntu.com/

      0x23E7166788B63E1E

    3. 單擊 pub鏈接,複製密鑰內容並保存到本地,以txt格式

      key.txt

      密鑰內容

    4. 終端添加密鑰

      sudo apt-key add key.txt

      ok

    5. 更新

      sudo apt update

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

※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

台中景泰電動車行只是一個單純的理由,將來台灣的環境,出門可以自由放心的深呼吸,讓空氣回歸自然的乾淨,減少污染,留給我們下一代有好品質無空污的優質環境